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

关于NSubstitute的测试疑问:是测试替身还是真实业务代码?

关于NSubstitute测试替身的疑问解答

你测试的确实是替身(Stub/Mock)的返回结果,不是真实Calculator类的Add方法逻辑。

文档里的这个示例只是用来演示NSubstitute最基础的语法用法——教你怎么给替身的方法预设返回值,以及验证这个预设是否生效,本质上是在展示工具的使用方式,不是用来测试真实业务代码的。

这种替身的核心意义在于隔离依赖,聚焦目标代码的测试,具体场景包括:

  • 隔离复杂依赖:如果你的业务代码依赖一个包含数据库、网络请求等复杂逻辑的组件,用替身可以跳过这些耗时或不稳定的环节,专注测试业务代码本身的逻辑是否正确。
  • 模拟异常/边界场景:真实组件可能很难触发某些异常或边界情况,比如网络超时、参数越界报错,通过替身可以轻松模拟这些场景,验证你的代码是否能正确处理。
  • 验证交互逻辑:除了预设返回值,你还可以用NSubstitute验证目标代码是否按照预期调用了依赖组件的方法——比如调用次数、传入参数是否正确,这才是替身更常用的测试场景。举个例子:
    // 验证目标代码是否调用过calculator.Add(1,2)
    calculator.Received().Add(1, 2);
    

举个更贴近真实开发的例子:
假设你有一个OrderService类,它依赖ICalculator来计算订单总价:

public class OrderService {
    private readonly ICalculator _calculator;
    public OrderService(ICalculator calculator) {
        _calculator = calculator;
    }
    public decimal CalculateTotal(decimal unitPrice, int count) {
        // 调用计算器的乘法计算总价
        return _calculator.Multiply(unitPrice, count);
    }
}

测试OrderService时,就可以用NSubstitute的替身来隔离ICalculator:

// 创建ICalculator接口的替身
var calculator = Substitute.For<ICalculator>();
// 预设:当调用Multiply(10, 3)时返回30
calculator.Multiply(10, 3).Returns(30);
// 实例化要测试的OrderService,传入替身
var orderService = new OrderService(calculator);
// 调用业务方法
var total = orderService.CalculateTotal(10, 3);
// 断言计算结果是否符合预期
Assert.That(total, Is.EqualTo(30));
// 验证OrderService是否正确调用了计算器的Multiply方法
calculator.Received().Multiply(10, 3);

这个测试里,我们不需要关心ICalculator的真实实现是否正确(那是Calculator类自己的单元测试要做的事),只需要验证OrderService是否正确使用了依赖的计算器来完成总价计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:16:08