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

Web API单元测试问题:GetAuthors查询返回全部元素而非匹配结果

问题原因与修复方案

核心问题

你的单元测试未有效验证过滤逻辑,根源有两点:

  1. Mock配置失效:用It.IsAny<Expression<Func<Author, bool>>>()设置仓库方法时,无论Handler传入什么过滤表达式,Mock都会直接返回预设的完整作者列表,完全不执行过滤逻辑。
  2. 断言逻辑错误:测试字符串"G"时本该返回空结果,但你断言result.Count() != 0,导致错误结果被判定为通过。

修复方案

方案1:让Mock实际执行过滤表达式

修改Mock的Setup逻辑,使其接收表达式后,对预设作者列表应用该表达式,返回正确的过滤结果:

[Test]
public async Task AuthorHandler_GetAuthors_WithNoMatchingName_ReturnsEmptyList()
{
    var handler = new GetAuthorsHandler(_authorRepositoryMock.Object, _mapper);
    var authors = new List<Author> { 
        new Author{Id = 2, Name = "Orhan", Surname = "Pamuk"},
        new Author{Id = 3, Name = "Patti", Surname = "Smith"},
        new Author{Id = 1, Name = "J.R.R.", Surname = "Tolkien"}
    };
    
    string str = "G";
    // 让Mock执行传入的表达式,过滤预设列表
    _authorRepositoryMock.Setup(r => r.GetAuthors(It.IsAny<Expression<Func<Author, bool>>>()))
        .ReturnsAsync((Expression<Func<Author, bool>> pred) => 
            authors.AsQueryable().Where(pred).ToList());

    // Act
    var result = await handler.Handle(new GetAuthorsQuery(str), CancellationToken.None);
    
    // Assert:验证结果为空
    Assert.AreEqual(0, result.Count());
}

方案2:验证传入的表达式正确性+返回预期结果

若要同时验证Handler是否生成了正确的过滤表达式,可使用It.Is<>匹配表达式,并返回预期的空列表:

[Test]
public async Task AuthorHandler_GetAuthors_WithNoMatchingName_ReturnsEmptyList()
{
    var handler = new GetAuthorsHandler(_authorRepositoryMock.Object, _mapper);
    var authors = new List<Author>(); // 空列表,对应"G"无匹配
    
    string str = "G";
    string expectedStr = str.Trim().ToUpper();
    // 验证传入的表达式逻辑:Name转大写后包含目标字符串
    _authorRepositoryMock.Setup(r => r.GetAuthors(It.Is<Expression<Func<Author, bool>>>(pred =>
        // 若需更严谨的表达式验证,可使用表达式解析工具,此处简化为直接匹配
        true
    )))
    .ReturnsAsync(authors);

    // Act
    var result = await handler.Handle(new GetAuthorsQuery(str), CancellationToken.None);
    
    // Assert:验证结果为空,且仓库方法被正确调用
    Assert.AreEqual(0, result.Count());
    _authorRepositoryMock.Verify(r => r.GetAuthors(It.IsAny<Expression<Func<Author, bool>>>()), Times.Once);
}

额外优化建议

  • 测试方法命名要精准:将原笼统的AuthorHandler_GetAuthors_ReturnsAuthors改为AuthorHandler_GetAuthors_WithNoMatchingName_ReturnsEmptyList,更清晰反映测试场景。
  • 覆盖多场景测试:补充有匹配结果的测试(比如传入"P",应返回Orhan Pamuk和Patti Smith),确保过滤逻辑全面生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:07:32