模拟FindAsync方法

时间:2017-04-12 12:22:57

标签: c# .net entity-framework unit-testing moq

我通过以下代码模拟了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返回null。为了使它工作,我添加了以下模拟:

mockContext.Setup(m => m.Set<Brand>().FindAsync(It.IsAny<object[]>()))
    .Returns<object[]>(async d => await brands.Object.FindAsync(d));

任何人都知道为什么会发生这种情况?

2 个答案:

答案 0 :(得分:1)

IMO,您应该模拟接口,例如IBrandRepository。否则是什么嘲弄? - 您可以创建类的实例,调用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(), ...

答案 1 :(得分:0)

Dimitry,我知道已经过去两年了。我只是遇到了同样的问题,这就是我为使其正常工作所做的

this.mocContext.Setup(x => x.Company.FindAsync(It.IsAny<string> 
())).Returns(Task.FromResult(this.GetCompanyList().SingleOrDefault(x => 
x.CompanyCode.Equals("M5QoKF4AS0"))));

这是mocContext是我的Moq数据库,Company是我要对其执行FindAsync的表,Get CompanyList只是从填充表的数据中提取。希望这会有所帮助