• NSubstitute完全手册(一)入门基础


    NSubstitute入门

    最简单的入门方式就是创建一个测试项目,并将 NSubstitute 引用到其中。可以通过 NuGetOpenWrap 来获取 NSubstitute 包。也可以直接下载 NSubstitute 文件,然后将 NSubstitute.dll 引用到项目中。

    然后就可以创建一个新的测试 Fixture(可以选择使用你最喜欢的UT测试框架,本文涉及的示例中我们使用MSTest),开始思考从哪里入手。

    首先,添加 using NSubstitute; 到当前的C#代码文件中,有了它我们就可以开始创建替身了。

    现在,比如我们有一个非常简单的计算器接口:

    1     public interface ICalculator
    2     {
    3       int Add(int a, int b);
    4       string Mode { get; set; }
    5       event EventHandler PoweringUp;
    6     }

    我们可以让NSubstitute来创建类型实例的替代实例。可以创建诸如 Stub、Mock、Fake、Spy、Test Double 等,但当我们只是想要一个能有一定程度控制的替代实例时,为什么我们要困扰于此呢?

    1     [TestMethod]
    2     public void Test_GetStarted_GetSubstitute()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5     }

    现在,我们可以告诉被创建的替代实例,当方法被调用时返回一个值:

    1     [TestMethod]
    2     public void Test_GetStarted_ReturnSpecifiedValue()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5       calculator.Add(1, 2).Returns(3);
    6 
    7       int actual = calculator.Add(1, 2);
    8       Assert.AreEqual<int>(3, actual);
    9     }

    我们可以检查该替代实例是否接收到了一个指定的调用,或者未收到某指定调用:

    1     [TestMethod]
    2     public void Test_GetStarted_ReceivedSpecificCall()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5       calculator.Add(1, 2);
    6 
    7       calculator.Received().Add(1, 2);
    8       calculator.DidNotReceive().Add(5, 7);
    9     }

    如果 Received() 断言失败,NSubstitute 会尝试给出有可能是什么问题:

    1     [TestMethod]
    2     [ExpectedException(typeof(ReceivedCallsException))]
    3     public void Test_GetStarted_DidNotReceivedSpecificCall()
    4     {
    5       ICalculator calculator = Substitute.For<ICalculator>();
    6       calculator.Add(5, 7);
    7 
    8       calculator.Received().Add(1, 2);
    9     }
    Expected to receive a call matching:
        Add(1, 2)
    Actually received no matching calls.
    Received 1 non-matching call (non-matching arguments indicated with '*' characters):
        Add(*5*, *7*)

    我们也可以对属性使用与方法类似的 Retures() 语法,或者继续使用简单的属性 setter 来设置返回值。

     1     [TestMethod]
     2     public void Test_GetStarted_SetPropertyValue()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Mode.Returns("DEC");
     7       Assert.AreEqual<string>("DEC", calculator.Mode);
     8 
     9       calculator.Mode = "HEX";
    10       Assert.AreEqual<string>("HEX", calculator.Mode);
    11     }

    NSubstitute 支持参数匹配功能,可以设置参数规则,并断言判断是否接收到参数匹配的调用。

     1     [TestMethod]
     2     public void Test_GetStarted_MatchArguments()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Add(10, -5);
     7 
     8       calculator.Received().Add(10, Arg.Any<int>());
     9       calculator.Received().Add(10, Arg.Is<int>(x => x < 0));
    10     }

    我们也可以在使用参数匹配功能的同时,传递一个函数给 Returns() ,以此来使替代实例具有更多的功能。

     1     [TestMethod]
     2     public void Test_GetStarted_PassFuncToReturns()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       calculator
     6          .Add(Arg.Any<int>(), Arg.Any<int>())
     7          .Returns(x => (int)x[0] + (int)x[1]);
     8 
     9       int actual = calculator.Add(5, 10);
    10 
    11       Assert.AreEqual<int>(15, actual);
    12     }

    Returns() 也可通过构造一个返回值序列来指定多个参数。

     1     [TestMethod]
     2     public void Test_GetStarted_MultipleValues()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       calculator.Mode.Returns("HEX", "DEC", "BIN");
     6 
     7       Assert.AreEqual<string>("HEX", calculator.Mode);
     8       Assert.AreEqual<string>("DEC", calculator.Mode);
     9       Assert.AreEqual<string>("BIN", calculator.Mode);
    10     }

    最后,我们可以在替代实例上引发事件通知:

     1     [TestMethod]
     2     public void Test_GetStarted_RaiseEvents()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       bool eventWasRaised = false;
     6 
     7       calculator.PoweringUp += (sender, args) =>
     8       {
     9         eventWasRaised = true;
    10       };
    11 
    12       calculator.PoweringUp += Raise.Event();
    13 
    14       Assert.IsTrue(eventWasRaised);
    15     }

    基本上这些就是入门 NSubstitute 的全部内容。对于更详细的功能说明,以及一些 NSubstitute 所支持的不太常用的需求,请继续阅读

    NSubstitute 完全手册

  • 相关阅读:
    JMeter分布式压测-常见问题之( Cannot start. localhost.localdomain is a loopback address)
    Jmeter实现multipart/form-data类型请求
    【漫画算法最后章节】【算法运用】 —— Bitmap算法的巧用
    整数类型
    宁波多校(一) E题 ddd的逛街计划(Easy Version)
    宁波多校(一) D题 COLORS的字符串挑战(线段树+hash+二分)
    CF1361D Johnny and James(模拟)
    CF1363F Rotating Substrings(dp)
    CF1363E Tree Shuffling(贪心+树上乱搞)
    AcWing1185 单词游戏(欧拉路径)
  • 原文地址:https://www.cnblogs.com/gaochundong/p/nsubstitute_get_started.html
Copyright © 2020-2023  润新知