c# - NSubstitute .Returns<T>() 是如何工作的?

标签 c# mocking nsubstitute

如何.Returns<T> (this T value, ... )扩展方法在幕后工作?

具体来说,.Returns是如何实现的?仅从执行该方法的结果就知道要配置什么方法?

例子:

public interface ICalculator { Add(int a, int b); }

// create mock
var calculator = Substitute.For<ICalculator>();

// How does this piece work under the hood?
calculator.Add(1, 2).Returns(3);

最佳答案

每当替代者收到调用时,它会记录有关调用的信息,并更新一些全局状态(线程本地,as Scott pointed out)记录它是最近调用的替代者。

.Returns 运行时,它会查找最后调用的替代,然后告诉替代它的最后一次调用应该被 stub 以返回该特定值。 (它还将它从已接收调用的集合中删除,因此如果我们运行 .Received(), stub 调用不会与真实调用混淆。)

calculator
    .Add(1, 2)   // substitute records Add(1,2) called. Last substitute
                 // set to `calculator`. Returns default `int` in this case.
    .Returns(3)  // Looks up last sub, sets its last call to return 3.

我认为这是对所发生情况的合理近似。为了在您想要查看代码时增加一点精度,替代品是 dynamic proxy哪个forwards每次调用“call router”,它处理替代品的所有逻辑(存储调用、配置调用、添加回调等)。全局状态是 SubstitutionContext , 它存储最后一个收到调用的调用路由器。

( repo 链接到 v4.0.0-rc1 标签。以后的版本可能会改变,但总体思路应该保持相当一致。)

关于c# - NSubstitute .Returns<T>() 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39410333/

相关文章:

c# - 我如何在 LINQ 查询中执行此聚合、分组依据?

c# - NSubstitute 模拟一个没有参数的 void 方法

c# - Xamarin 中的 NUnit 异步测试不起作用

java - 如何模拟注入(inject)属性文件值的字符串值?

json - 单元测试 REST API

ruby - 回到 rspec-mocks 中的原始方法

c# - 在设计时代码中使用模拟框架的缺点

mocking - 生成的服务模拟 : everything but RhinoMocks fails?

c# - nUnit 中的 ExpectedException 给了我一个错误

C#、ASP.NET - 从数据库收集数据