仅返回数据库过滤列表的EF Core代码,需做哪些单元测试?
你这段搜索方法的单元测试场景可以从这几个维度入手
核心匹配逻辑验证
- 完全匹配场景:准备包含与搜索字符串完全一致名称的Drug数据,验证返回结果中存在该条目
- 部分匹配场景:数据库中有名称包含搜索片段的Drug(比如搜"asp",数据有"Aspirin"),验证这些条目都被返回
- 大小写不敏感验证:搜索字符串与Drug名称大小写不同(如搜"paracetamol",数据有"Paracetamol"),确认能正常匹配返回
- 首尾空格处理验证:搜索字符串带前后空格(如" aspirin "),验证Trim生效,仍能正确匹配目标数据
边界与异常场景
- 空搜索字符串:当
search.SearchString为空时,验证是否返回所有Drug(因为原代码中Contains("")会匹配所有条目,这是EF的默认行为,需要确认是否符合业务预期) - 无匹配结果:数据库中没有任何Drug名称包含搜索字符串,验证返回空列表
- 搜索字符串为null:如果业务允许
SearchString为null,测试此场景(原代码直接调用Trim()会抛出空引用异常,这可能是个潜在bug,需要验证) - 空数据库场景:数据库中没有任何Drug数据,无论搜索什么都返回空列表
异步与类型验证
- 异步执行验证:通过测试框架的异步断言(如xUnit的
Assert.IsType<Task<List<Drug>>>),确认方法确实是异步执行 - 返回类型验证:验证返回结果是
List<Drug>,而非IQueryable或其他类型
测试代码示例(用Moq模拟依赖)
using Moq; using Xunit; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; public class DrugServiceTests { private readonly Mock<IUnitOfWork> _mockUnitOfWork; private readonly Mock<IDrugRepository> _mockDrugRepo; private readonly DrugService _drugService; public DrugServiceTests() { _mockDrugRepo = new Mock<IDrugRepository>(); _mockUnitOfWork = new Mock<IUnitOfWork>(); _mockUnitOfWork.Setup(u => u.DrugRepository).Returns(_mockDrugRepo.Object); _drugService = new DrugService(_mockUnitOfWork.Object); } [Fact] public async Task SearchDrugs_PartialCaseInsensitiveMatch_ReturnsCorrectItems() { // 准备测试数据 var testDrugs = new List<Drug> { new Drug { Name = "Aspirin" }, new Drug { Name = "Ibuprofen" }, new Drug { Name = "Aspirin Protect" } }; _mockDrugRepo.Setup(repo => repo.Get()).Returns(testDrugs.AsQueryable()); // 执行搜索,搜索字符串是小写的"asp" var result = await _drugService.SearchDrugs(new SearchCatalogItemRequest { SearchString = "asp" }); // 断言结果数量为2,且包含对应的Drug Assert.Equal(2, result.Count); Assert.Contains(result, d => d.Name == "Aspirin"); Assert.Contains(result, d => d.Name == "Aspirin Protect"); } [Fact] public async Task SearchDrugs_SearchStringIsNull_ThrowsNullReferenceException() { // 空数据 _mockDrugRepo.Setup(repo => repo.Get()).Returns(new List<Drug>().AsQueryable()); // 执行搜索,SearchString为null await Assert.ThrowsAsync<NullReferenceException>(() => _drugService.SearchDrugs(new SearchCatalogItemRequest { SearchString = null })); } }
内容的提问来源于stack exchange,提问作者Ankad
相关产品推荐
相关产品推荐

