模拟 FindAsync 方法
Mocking FindAsync method
我通过以下代码模拟了 FindAsync:
var brands = new Mock<DbSet<Brand>>();
ConfigureTheDbSet(brands, brandData);
brands.Setup(b => b.FindAsync(It.IsAny<object[]>())) //substitution of the .SelectAsync(id) method
.Returns<object[]>(ids => brands.Object.FirstOrDefaultAsync(b => b.BrandId == (int) ids[0]));
在我将 AsNoTracking 模拟添加到上下文之前它一直正常工作:
var mockContext = new Mock<ReportDbContext>();
mockContext.Setup(m => m.Set<Brand>()).Returns(brands.Object);
mockContext.Setup(m => m.Set<Brand>().AsNoTracking()).Returns(brands.Object);
而 FindAsync returns 为空。为了让它工作,我添加了以下模拟:
mockContext.Setup(m => m.Set<Brand>().FindAsync(It.IsAny<object[]>()))
.Returns<object[]>(async d => await brands.Object.FindAsync(d));
有人知道为什么会这样吗?
IMO,您应该模拟接口,例如 IBrandRepository。否则嘲笑的意义何在? - 您可以创建 class 的实例,调用 FindAsync() 并像往常一样断言结果..
以下是我如何将 Moq 与接口一起使用,例如 repo 接口;
// arrange
var mockRepo = new Mock<IBrandRepository>();
mockRepo.Setup(o => o.FindAsync(It.IsAny<string>())).ReturnsAsync(new Brand[] { ... });
var someClass = new SomeClass(IBrandRepository); // someClass that use IBrandRepository
// act
string search = "brand1 brand2"; // what the user searches for
var results = someClass.FindBrands(searchText) // internally calls IBrandRepository.FindAsync()
// assert
// Assert.AreEqual(results.Count(), ...
Dimitry,我知道已经有几年了。我只是遇到了同样的问题,这就是我为使其正常工作所做的工作
this.mocContext.Setup(x => x.Company.FindAsync(It.IsAny<string>
())).Returns(Task.FromResult(this.GetCompanyList().SingleOrDefault(x =>
x.CompanyCode.Equals("M5QoKF4AS0"))));
这里 mocContext 是我的 Moq'd 数据库,Company 是我要对其执行 FindAsync 的 table,Get CompanyList 只是从填充 table 的数据中提取。希望这对您有所帮助
我通过使用 .Where(entity => entity.PrimaryKey == key).FirstOrDefaultAsync()
代替 .FindAsync(key)
来规避这种模拟,因为 FirstOrDefaultAsync
不需要单独的模拟并且两种方法之间的逻辑也相同
我通过以下代码模拟了 FindAsync:
var brands = new Mock<DbSet<Brand>>();
ConfigureTheDbSet(brands, brandData);
brands.Setup(b => b.FindAsync(It.IsAny<object[]>())) //substitution of the .SelectAsync(id) method
.Returns<object[]>(ids => brands.Object.FirstOrDefaultAsync(b => b.BrandId == (int) ids[0]));
在我将 AsNoTracking 模拟添加到上下文之前它一直正常工作:
var mockContext = new Mock<ReportDbContext>();
mockContext.Setup(m => m.Set<Brand>()).Returns(brands.Object);
mockContext.Setup(m => m.Set<Brand>().AsNoTracking()).Returns(brands.Object);
而 FindAsync returns 为空。为了让它工作,我添加了以下模拟:
mockContext.Setup(m => m.Set<Brand>().FindAsync(It.IsAny<object[]>()))
.Returns<object[]>(async d => await brands.Object.FindAsync(d));
有人知道为什么会这样吗?
IMO,您应该模拟接口,例如 IBrandRepository。否则嘲笑的意义何在? - 您可以创建 class 的实例,调用 FindAsync() 并像往常一样断言结果..
以下是我如何将 Moq 与接口一起使用,例如 repo 接口;
// arrange
var mockRepo = new Mock<IBrandRepository>();
mockRepo.Setup(o => o.FindAsync(It.IsAny<string>())).ReturnsAsync(new Brand[] { ... });
var someClass = new SomeClass(IBrandRepository); // someClass that use IBrandRepository
// act
string search = "brand1 brand2"; // what the user searches for
var results = someClass.FindBrands(searchText) // internally calls IBrandRepository.FindAsync()
// assert
// Assert.AreEqual(results.Count(), ...
Dimitry,我知道已经有几年了。我只是遇到了同样的问题,这就是我为使其正常工作所做的工作
this.mocContext.Setup(x => x.Company.FindAsync(It.IsAny<string>
())).Returns(Task.FromResult(this.GetCompanyList().SingleOrDefault(x =>
x.CompanyCode.Equals("M5QoKF4AS0"))));
这里 mocContext 是我的 Moq'd 数据库,Company 是我要对其执行 FindAsync 的 table,Get CompanyList 只是从填充 table 的数据中提取。希望这对您有所帮助
我通过使用 .Where(entity => entity.PrimaryKey == key).FirstOrDefaultAsync()
代替 .FindAsync(key)
来规避这种模拟,因为 FirstOrDefaultAsync
不需要单独的模拟并且两种方法之间的逻辑也相同