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

如何用NSubstitute监视模拟方法返回值?Received返回null问题求助

解决NSubstitute中Received()获取返回值为null的问题

我来帮你拆解下这个问题的核心原因,再给你两种实用的解决方案:

问题根源

你这里踩了一个NSubstitute的常见误区:Received()方法的作用是验证模拟对象的方法是否被调用了指定次数,它返回的是模拟对象本身,而不是之前那次调用的返回值。

在你的代码里,factory.Received(1).Create()实际做了两件事:

  1. 验证factory.Create()确实被调用了1次
  2. 再次调用了模拟对象的Create()方法,但这次调用没有设置返回值,所以NSubstitute返回了默认值null

这就是为什么factoryResult会是null,而不是你预期的SomeMethod()里拿到的那个对象。

解决方案

方案1:提前保存返回实例(最简单直接)

如果能提前确定工厂要返回的对象,直接在设置Returns时保存引用,之后用这个引用做断言即可:

[Fact]
void TestMethod() {
    var factory = Substitute.For<IFactory>();
    // 提前创建并保存要返回的对象
    var expectedObject = new object();
    factory.Create().Returns(expectedObject);
    
    IMockable mockable = new Mockable(factory);
    object mockableResult = mockable.SomeMethod();
    
    // 先验证调用次数,再用保存的对象做断言
    factory.Received(1).Create();
    Assert.Equal(expectedObject, mockableResult);
}

方案2:通过调用记录提取返回值(适合动态场景)

如果返回对象是动态生成的(比如你的代码里用x => new object()),可以通过ReceivedCalls()获取所有调用记录,再提取对应返回值:

[Fact]
void TestMethod() {
    var factory = Substitute.For<IFactory>();
    factory.Create().Returns(x => new object());
    
    IMockable mockable = new Mockable(factory);
    object mockableResult = mockable.SomeMethod();
    
    // 筛选出Create方法的调用记录
    var createCall = factory.ReceivedCalls()
        .First(call => call.GetMethodInfo().Name == nameof(IFactory.Create));
    // 提取这次调用的返回值
    object factoryResult = createCall.GetReturnValue();
    
    Assert.Equal(mockableResult, factoryResult);
}

关键提醒

记住NSubstitute的Received()是用来做调用次数验证的,不是用来获取历史返回值的。如果需要验证返回结果,要么提前保存实例,要么通过调用记录来提取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:02:42