1. culage

    Posted

    culage
Changes in title
+NSubstitute チートシート
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,162 @@
+## NSubstitute とは
+
+ユニットテストで利用することを想定した、.NET Framework 向けのMockライブラリ。
+元となるインターフェースやクラスからテストで利用するためのモックオブジェクトを作成する。
+
+公式サイト: http://nsubstitute.github.io/
+
+
+## チートシート
+
+### 生成
+
+- interfaceからモック生成
+`var calculator = Substitute.For<ICalculator>();`
+
+- 実クラスからモック生成 (仮想メンバのみをモック化。それ以外は実際に実行される)
+`var calculator = Substitute.For<CalculatorClass>();`
+
+
+### 挙動を設定
+
+- 戻り値設定
+`calculator.Add(1, 1).ReturnsForAnyArgs(99);`
+
+- 戻り値設定 (特定引数)
+`calculator.Add(1, 2).Returns(3);`
+
+- 処理呼び出し
+`calculator.Add(1, 1).ReturnsForAnyArgs(x => Console.Log("called."));`
+
+- 1回目は10, 2回目は20を返す
+`calculator.Add(1, 1).ReturnsForAnyArgs(10, 20);`
+
+
+### 呼び出し結果確認
+
+以下を実行すると、確認結果が正しくなかったときにReceivedCallsExceptionが発生。
+
+- 呼び出されたことを確認
+`calculator.ReceivedWithAnyArgs().Add(1, 1);`
+
+- 呼び出されたことを確認 (特定引数)
+`calculator.Received().Add(1, 2);`
+
+- 呼び出された回数確認
+calculator.ReceivedWithAnyArgs(3).Add(1, 1);
+
+- プロパティが呼び出されたことを確認
+`var dummy = calculator.Received().prop; // getter
+calculator.Received().prop = "hoge"; // setter`
+
+- 呼び出し状態クリア
+`calculator.ClearReceivedCalls();`
+
+
+## (付録) unityでの利用方法
+
+以下URLからdllのバイナリを取得
+https://github.com/nsubstitute/NSubstitute/downloads
+
+(解凍フォルダ)\lib\NET35\NSubstitute.dll
+……をunityの"Assets/Plugins"以下へコピー
+
+以下のようなC#ファイルを作成してTestRunnerで実行
+
+```C#
+using UnityEngine;
+using UnityEngine.TestTools;
+using NUnit.Framework;
+using NSubstitute;
+
+public interface ISample {
+ int Hoge();
+}
+
+public class NSubstituteTest {
+ [Test]
+ public void SubstituteTest() {
+ var mockSample = Substitute.For<ISample>();
+ mockSample.Hoge().Returns(99);
+
+ Assert.AreEqual(99, mockSample.Hoge());
+ }
+}
+```
+
+## (付録) サンプルコード
+
+```C#
+using UnityEngine;
+using UnityEngine.TestTools;
+using NUnit.Framework;
+using NSubstitute;
+
+// モック作成元のインターフェース
+public interface ISample {
+ int Hoge();
+ int Fuga(int n);
+ int hogeProp { get; set; }
+}
+
+public class NSubstituteTest {
+ // 挙動を設定
+ [Test]
+ public void Returns() {
+ // モックの作成
+ var mockSample = Substitute.For<ISample>();
+
+ // 戻り値設定
+ mockSample.Hoge().ReturnsForAnyArgs(99);
+ Assert.AreEqual(99, mockSample.Hoge());
+
+ // 戻り値設定 (特定引数)
+ mockSample.Fuga(0).Returns(99);
+ Assert.AreEqual(99, mockSample.Fuga(0));
+
+ // 処理呼び出し
+ mockSample.Fuga(2).Returns(n => { Debug.Log("called."); return 0; });
+ mockSample.Fuga(2);
+
+ // 1回目は10, 2回目は20を返す
+ mockSample.Fuga(1).Returns(10, 20);
+ Assert.AreEqual(10, mockSample.Fuga(1));
+ Assert.AreEqual(20, mockSample.Fuga(1));
+ }
+
+ // 呼び出し結果確認
+ [Test]
+ public void Received() {
+ // モックの作成
+ var mockSample = Substitute.For<ISample>();
+
+ // 呼び出されたことを確認
+ mockSample.Hoge();
+ mockSample.ReceivedWithAnyArgs().Hoge();
+
+ // 呼び出されたことを確認 (特定引数)
+ mockSample.Fuga(1);
+ mockSample.Received().Fuga(1);
+ mockSample.DidNotReceive().Fuga(2);
+
+ // 呼び出された回数確認
+ mockSample.ReceivedWithAnyArgs(1).Fuga(1);
+ mockSample.Fuga(9);
+ mockSample.Fuga(9);
+ mockSample.ReceivedWithAnyArgs(3).Fuga(1);
+
+ // プロパティが呼び出されたことを確認
+ var dummy = mockSample.DidNotReceive().hogeProp;
+ dummy = mockSample.hogeProp;
+ dummy = mockSample.Received().hogeProp;
+
+ mockSample.DidNotReceive().hogeProp = 1;
+ mockSample.hogeProp = 1;
+ mockSample.Received().hogeProp = 1;
+
+ // 呼び出し状態クリア
+ mockSample.ClearReceivedCalls();
+ mockSample.Received(0).Hoge();
+ }
+}
+```