如何用NSubstitute监视模拟方法返回值?Received返回null问题求助
解决NSubstitute中Received()获取返回值为null的问题
我来帮你拆解下这个问题的核心原因,再给你两种实用的解决方案:
问题根源
你这里踩了一个NSubstitute的常见误区:Received()方法的作用是验证模拟对象的方法是否被调用了指定次数,它返回的是模拟对象本身,而不是之前那次调用的返回值。
在你的代码里,factory.Received(1).Create()实际做了两件事:
- 验证
factory.Create()确实被调用了1次 - 再次调用了模拟对象的
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
相关产品推荐
相关产品推荐

