【问题标题】:Mocking FindAsync method模拟 FindAsync 方法
【发布时间】:2017-09-08 05:27:30
【问题描述】:

我通过以下代码模拟了 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));

有人知道为什么会这样吗?

【问题讨论】:

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


    【解决方案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(), ...
    

    【讨论】:

    • 这没有意义,因为我模拟了传递给服务的上下文并定义了服务行为
    【解决方案2】:

    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 的表,Get CompanyList 只是从填充表的数据中提取。希望这会有所帮助

    【讨论】:

      【解决方案3】:

      我通过使用.Where(entity =&gt; entity.PrimaryKey == key).FirstOrDefaultAsync() 代替.FindAsync(key) 来规避这种模拟,因为FirstOrDefaultAsync 不需要单独的模拟,并且两种方法之间的逻辑也是相同的

      【讨论】:

        猜你喜欢
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多