博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NSubstitute完全手册(九)检查接收到的调用
阅读量:7187 次
发布时间:2019-06-29

本文共 6645 字,大约阅读时间需要 22 分钟。

在某些情况下(尤其是对void方法),检测替代实例是否能成功接收到一个特定的调用是非常有用的。可以通过使用 Received() 扩展方法,并紧跟着被检测的方法。

1     public interface ICommand 2     { 3       void Execute(); 4       event EventHandler Executed; 5     } 6  7     public class SomethingThatNeedsACommand 8     { 9       ICommand command;10       public SomethingThatNeedsACommand(ICommand command)11       {12         this.command = command;13       }14       public void DoSomething() { command.Execute(); }15       public void DontDoAnything() { }16     }17 18     [TestMethod]19     public void Test_CheckReceivedCalls_CallReceived()20     {21       //Arrange22       var command = Substitute.For
();23 var something = new SomethingThatNeedsACommand(command);24 25 //Act26 something.DoSomething();27 28 //Assert29 command.Received().Execute();30 }

在这个例子中,command 收到了一个对 Execute() 方法的调用,所以会顺利地完成。如果没有收到对 Execute() 的调用,则 NSubstitute 会抛出一个 ReceivedCallsException 异常,并且会显示具体是在期待什么方法被调用,参数是什么,以及列出实际的方法调用和参数。

检查一个调用没有被收到

通过使用 DidNotReceive() 扩展方法,NSubstitute 可以确定一个调用未被接收到。
1     [TestMethod] 2     public void Test_CheckReceivedCalls_CallDidNotReceived() 3     { 4       //Arrange 5       var command = Substitute.For
(); 6 var something = new SomethingThatNeedsACommand(command); 7 8 //Act 9 something.DontDoAnything();10 11 //Assert12 command.DidNotReceive().Execute();13 }

检查接收到指定次数的调用

Received() 扩展方法会对某成员的至少一次的调用进行断言,DidNotReceive() 则会断言未收到调用。NSubstitute 也提供允许断言某调用是否接收到了指定的次数的选择,通过传递一个整型值给 Received() 方法。如果替代实例没有接收到给定的次数,则将会抛出异常。接收到的次数少于或多于给定次数,断言会失败。
1     public class CommandRepeater 2     { 3       ICommand command; 4       int numberOfTimesToCall; 5       public CommandRepeater(ICommand command, int numberOfTimesToCall) 6       { 7         this.command = command; 8         this.numberOfTimesToCall = numberOfTimesToCall; 9       }10 11       public void Execute()12       {13         for (var i = 0; i < numberOfTimesToCall; i++) command.Execute();14       }15     }16 17     [TestMethod]18     public void Test_CheckReceivedCalls_CallReceivedNumberOfSpecifiedTimes()19     {20       // Arrange21       var command = Substitute.For
();22 var repeater = new CommandRepeater(command, 3);23 24 // Act25 repeater.Execute();26 27 // Assert28 // 如果仅接收到2次或者4次,这里会失败。29 command.Received(3).Execute();30 }

Received(1) 会检查该调用收到并且仅收到一次。这与默认的 Received() 不同,其检查该调用至少接收到了一次。Received(0) 的行为与 DidNotReceive() 相同。

接收到或者未接收到指定的参数

我们也可以使用参数匹配器来检查是否收到了或者未收到包含特定参数的调用。在 一节会介绍更多细节,下面的例子演示了一般用法:
1     public interface ICalculator 2     { 3       int Add(int a, int b); 4       string Mode { get; set; } 5     } 6  7     [TestMethod] 8     public void Test_CheckReceivedCalls_CallReceivedWithSpecificArguments() 9     {10       var calculator = Substitute.For
();11 12 calculator.Add(1, 2);13 calculator.Add(-100, 100);14 15 // 检查接收到了第一个参数为任意值,第二个参数为2的调用16 calculator.Received().Add(Arg.Any
(), 2);17 // 检查接收到了第一个参数小于0,第二个参数为100的调用18 calculator.Received().Add(Arg.Is
(x => x < 0), 100);19 // 检查未接收到第一个参数为任意值,第二个参数大于等于500的调用20 calculator21 .DidNotReceive()22 .Add(Arg.Any
(), Arg.Is
(x => x >= 500));23 }

忽略参数

就像我们可以 一样,NSubstitute 可以检查收到或者未收到调用,同时忽略其中包含的参数。此时我们需要使用 ReceivedWithAnyArgs() 和 DidNotReceiveWithAnyArgs()。
1     [TestMethod] 2     public void Test_CheckReceivedCalls_IgnoringArguments() 3     { 4       var calculator = Substitute.For
(); 5 6 calculator.Add(1, 3); 7 8 calculator.ReceivedWithAnyArgs().Add(1, 1); 9 calculator.DidNotReceiveWithAnyArgs().Subtract(0, 0);10 }

检查对属性的调用

同样的语法可以用于检查属性的调用。通常情况下,或许我们会避免这种检测,可能我们对所需的行为进行测试更感兴趣,而不是实现细节的精确性(例如,我们可以设置一个属性返回一个值,然后检测该值是否被合理的使用,而不是断言该属性的 getter 被调用了)。当然,有些时候检查 getter 和 setter 是否被调用仍然会派的上用场,所以,这里会介绍如何使用该功能:
1     [TestMethod] 2     public void Test_CheckReceivedCalls_CheckingCallsToPropeties() 3     { 4       var calculator = Substitute.For
(); 5 6 var mode = calculator.Mode; 7 calculator.Mode = "TEST"; 8 9 // 检查接收到了对属性 getter 的调用10 // 这里需要使用临时变量以通过编译11 var temp = calculator.Received().Mode;12 13 // 检查接收到了对属性 setter 的调用,参数为"TEST"14 calculator.Received().Mode = "TEST";15 }

检查调用索引器

其实索引器只是另外一个属性,所以我们可以使用相同的语法来检查索引器调用。
1     [TestMethod]2     public void Test_CheckReceivedCalls_CheckingCallsToIndexers()3     {4       var dictionary = Substitute.For
>();5 dictionary["test"] = 1;6 7 dictionary.Received()["test"] = 1;8 dictionary.Received()["test"] = Arg.Is
(x => x < 5);9 }

检查事件订阅

与属性一样,我们通常更赞成测试所需的行为,而非检查对特定事件的订阅。可以通过使用在替代实例上 ,并且断言我们的类在响应中执行的正确的行为:
1     public class CommandWatcher 2     { 3       ICommand command; 4       public CommandWatcher(ICommand command) 5       { 6         this.command = command; 7         this.command.Executed += OnExecuted; 8       } 9       public bool DidStuff { get; private set; }10       public void OnExecuted(object o, EventArgs e) 11       { 12         DidStuff = true; 13       }14     } 15 16     [TestMethod]17     public void Test_CheckReceivedCalls_CheckingEventSubscriptions()18     {19       var command = Substitute.For
();20 var watcher = new CommandWatcher(command);21 22 command.Executed += Raise.Event();23 24 Assert.IsTrue(watcher.DidStuff);25 }

当然,如果需要的话,Received() 会帮助我们断言订阅是否被收到:

1     [TestMethod] 2     public void Test_CheckReceivedCalls_MakeSureWatcherSubscribesToCommandExecuted() 3     { 4       var command = Substitute.For
(); 5 var watcher = new CommandWatcher(command); 6 7 // 不推荐这种方法。 8 // 更好的办法是测试行为而不是具体实现。 9 command.Received().Executed += watcher.OnExecuted;10 // 或者有可能事件处理器是不可访问的。11 command.Received().Executed += Arg.Any
();12 }

NSubstitute 完全手册

本文转自匠心十年博客园博客,原文链接:http://www.cnblogs.com/gaochundong/archive/2013/05/22/nsubstitute_checking_received_calls.html,如需转载请自行联系原作者
你可能感兴趣的文章
Vim的多窗口模式管理
查看>>
Android:EditText 设置弹出数字输入法键盘
查看>>
[Windows]Visual Studio Code个人配置
查看>>
防错笔记
查看>>
bzoj3232圈地游戏——0/1分数规划+差分建模+判环
查看>>
计算程序运行时间
查看>>
js 和后台交互
查看>>
Solr5.5高级应用(基于tomcat9)
查看>>
Linux企业运维人员最常用150个命令汇总
查看>>
使用js过滤字符串前后的空格
查看>>
22 October in 614
查看>>
Linux命令的那些事(一)
查看>>
Struts、Ajax、Restful、Web Service 狂想曲框架实现篇(三)
查看>>
PHP 过滤 及 字符转换 函数
查看>>
利用SOLR搭建企业搜索平台 之——solr的查询语法
查看>>
NSAIDs以优化剂量治疗中轴型SpA:聚焦6周期间骶髂关节MRI变化
查看>>
OCM读书笔记(2) - PL/SQL 基础
查看>>
二叉树遍历
查看>>
Q3.2 带有最小值或最大值的栈
查看>>
光流法简单介绍
查看>>