You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在xUnit中模拟含DeferredWhere与FirstOrDefaultAsync的LINQ代码

在xUnit中模拟DeferredWhere与FirstOrDefaultAsync的实现方案

假设_costOfConsomption是自定义仓储接口(比如ICostOfConsomptionRepository),我们可以用Moq框架完成模拟,以下是具体实现步骤:

1. 准备测试依赖与数据

首先确保项目已安装Moq和Moq.EntityFrameworkCore(依赖EF Core异步查询方法时需要),然后定义基础类型:

// 实体类示例
public class CostOfConsomption
{
    public int Id { get; set; }
    // 其他业务属性
}

// 仓储接口(需包含DeferredWhere方法)
public interface ICostOfConsomptionRepository
{
    IQueryable<CostOfConsomption> DeferredWhere(Expression<Func<CostOfConsomption, bool>> predicate);
}

2. 模拟找到数据的场景

当DeferredWhere传入匹配model.CostOfConsomptionId的条件时,返回包含目标实体的查询集合,确保FirstOrDefaultAsync能正常返回实体:

[Fact]
public async Task UpdateCost_WhenCostExists_ReturnsTargetCost()
{
    // Arrange
    var testCostId = 1;
    var testModel = new { CostOfConsomptionId = testCostId };
    var testCosts = new List<CostOfConsomption>
    {
        new CostOfConsomption { Id = testCostId }
    }.AsQueryable();

    var repoMock = new Mock<ICostOfConsomptionRepository>();
    repoMock.Setup(repo => repo.DeferredWhere(It.IsAny<Expression<Func<CostOfConsomption, bool>>>()))
            .Returns(testCosts);

    // 将mock注入被测服务
    var service = new YourBusinessService(repoMock.Object);

    // Act
    var result = await service.TargetMethod(testModel); // 调用包含目标代码的业务方法

    // Assert
    Assert.NotNull(result);
    Assert.Equal(testCostId, result.Id);
}

3. 模拟找不到数据的场景

当DeferredWhere返回空集合时,验证代码是否正确抛出NotFoundException:

[Fact]
public async Task UpdateCost_WhenCostDoesNotExist_ThrowsNotFoundException()
{
    // Arrange
    var testCostId = 999;
    var testModel = new { CostOfConsomptionId = testCostId };
    var emptyCosts = new List<CostOfConsomption>().AsQueryable();

    var repoMock = new Mock<ICostOfConsomptionRepository>();
    repoMock.Setup(repo => repo.DeferredWhere(It.IsAny<Expression<Func<CostOfConsomption, bool>>>()))
            .Returns(emptyCosts);

    var service = new YourBusinessService(repoMock.Object);

    // Act & Assert
    await Assert.ThrowsAsync<NotFoundException>(() => service.TargetMethod(testModel));
}

注意事项

  • 如果DeferredWhere是静态扩展方法,直接模拟会比较困难,建议将这类查询逻辑封装到仓储接口中,提升代码可测试性。
  • 使用Moq.EntityFrameworkCore可以更好地支持EF Core异步查询方法,无需手动模拟FirstOrDefaultAsync的返回任务。

内容的提问来源于stack exchange,提问作者Rezabk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:09:58