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 完全手冊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM