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

仅返回数据库过滤列表的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:10:47