Web API单元测试问题:GetAuthors查询返回全部元素而非匹配结果
问题原因与修复方案
核心问题
你的单元测试未有效验证过滤逻辑,根源有两点:
- Mock配置失效:用
It.IsAny<Expression<Func<Author, bool>>>()设置仓库方法时,无论Handler传入什么过滤表达式,Mock都会直接返回预设的完整作者列表,完全不执行过滤逻辑。 - 断言逻辑错误:测试字符串"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
相关产品推荐
相关产品推荐

