如何让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
相关产品推荐
相关产品推荐

