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

如何让NSubstitute开启严格模式,调用未模拟方法时默认抛出异常?

解决NSubstitute单元测试假通过问题(严格模式适用场景)

这一问题的核心解决方案是启用NSubstitute的严格模式(strict-mode),以下是该模式的典型适用场景:

  • 初始单元测试中,模拟了依赖项GetItemAsync方法返回null,测试正常通过。
  • 数周后模块内部实现变更,实际调用的是未模拟的GetDifferentItemAsync方法。
  • 由于NSubstitute默认对未模拟方法返回默认值/null,测试仍错误通过,无法感知实现变更带来的测试失效。
  • 直到QA反馈bug,才发现测试未正确校验当前实现逻辑。

失效的测试代码

[Fact]
public async void Handle_EntityNotFound_Throws()
{
    var request = new GetConfigTemplateRequest();
    var repository = Substitute.ForPartsOf<IRepository<ConfigTemplate>>();
    repository.GetItemAsync(Arg.Any<string>())
        .ReturnsNull();
    var requestHandler = new GetConfigTemplateRequestHandler(repository);

    var action = () => requestHandler.Handle(request, CancellationToken.None);

    await Assert.ThrowsAsync<EntityNotFoundException>(action);
}

修复后的测试代码(启用严格模式)

[Fact]
public async void Handle_EntityNotFound_Throws()
{
    var request = new GetConfigTemplateRequest();
    // 启用严格模式,未明确模拟的方法调用会抛出异常
    var repository = Substitute.For<IRepository<ConfigTemplate>>(SubstituteOptions.Strict);
    repository.GetDifferentItemAsync(/*特定匹配条件*/)
        .ReturnsNull();
    var requestHandler = new GetConfigTemplateRequestHandler(repository);

    var action = () => requestHandler.Handle(request, CancellationToken.None);

    await Assert.ThrowsAsync<EntityNotFoundException>(action);
}

关键说明

启用严格模式后,NSubstitute会对所有未明确模拟的方法调用抛出异常,彻底避免因默认返回值导致的测试假通过问题。当模块实现变更时,测试会立即失败,强制开发者同步更新测试用例,确保测试逻辑与实际实现一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:25:27