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

如何使用NSubstitute模拟运算符重载?测试ClassA时配置ClassB的*运算结果

在NSubstitute中模拟重载了*运算符的ClassB实例

要解决这个问题,得先搞清楚.NET中运算符重载的本质:所有运算符重载在编译后都会变成命名特殊的静态方法,比如二元*运算符对应的是op_Multiply静态方法。而NSubstitute的核心能力是模拟实例成员,直接处理静态运算符方法并不支持——不过我们可以通过重构代码或者间接模拟的方式实现需求。

下面分两种常见场景给出解决方案:


场景1:重构代码,将运算符逻辑委托给实例方法

这是最推荐的做法,既保持代码的可测试性,又符合单一职责原则。

假设你的ClassB原来的运算符重载是这样的:

public class ClassB
{
    public static ClassB operator *(ClassB left, int multiplier)
    {
        // 这里是运算符的逻辑
        return new ClassB(left.Value * multiplier);
    }

    public int Value { get; }
    public ClassB(int value) => Value = value;
}

我们可以把运算符的核心逻辑提取到一个实例方法中,让运算符直接调用这个方法:

public class ClassB
{
    public static ClassB operator *(ClassB left, int multiplier)
    {
        // 委托给实例方法
        return left.MultiplyBy(multiplier);
    }

    // 提取出的实例方法,用于核心逻辑
    public virtual ClassB MultiplyBy(int multiplier)
    {
        return new ClassB(Value * multiplier);
    }

    public int Value { get; }
    public ClassB(int value) => Value = value;
}

现在在测试中,你就可以用NSubstitute模拟这个MultiplyBy实例方法,从而间接控制*运算符的返回结果:

// 创建ClassB的模拟实例
var mockB = Substitute.For<ClassB>(10); // 构造函数参数按需传入

// 设置当调用MultiplyBy任意整数时,返回指定的ClassB实例
mockB.MultiplyBy(Arg.Any<int>()).Returns(new ClassB(100));

// 测试*运算:mockB * 5 会调用MultiplyBy(5),返回我们设置的实例
var result = mockB * 5;
Assert.AreEqual(100, result.Value);

场景2:如果无法重构ClassB(比如第三方类库)

如果ClassB是第三方类,你无法修改它的代码,那可以考虑包装一层适配器类,将运算符的调用转化为实例方法的调用,再模拟适配器。

比如创建一个ClassBWrapper:

public class ClassBWrapper
{
    private readonly ClassB _innerB;

    public ClassBWrapper(ClassB innerB) => _innerB = innerB;

    // 包装*运算符
    public virtual ClassB Multiply(int multiplier)
    {
        return _innerB * multiplier;
    }
}

然后在ClassA中依赖ClassBWrapper而不是直接依赖ClassB,测试时模拟ClassBWrapper的Multiply方法:

var mockWrapper = Substitute.For<ClassBWrapper>(new ClassB(10));
mockWrapper.Multiply(Arg.Any<int>()).Returns(new ClassB(200));

// 注入到ClassA中
var classA = new ClassA(mockWrapper);
// 后续测试逻辑...

关键注意点

  • NSubstitute不支持直接模拟静态方法(包括运算符对应的静态方法),所以必须通过实例方法的间接方式来处理。
  • 如果你遇到的是一元*运算符(比如指针解引用),对应的静态方法是op_UnaryMultiply,处理思路和上面一致——把逻辑提取到实例方法再模拟。

内容的提问来源于stack exchange,提问作者François

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:44:08