NDW

アプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

.NET Core 1. システムエンジニアリング 実装技術

.NET Core(C#): Moqのnew Mock<T>()とMock.Of<T>()の違い

投稿日:

はじめに

new Mock<T>()とMock.Of<T>()の違い

  • モック化対象オブジェクトを作成したいだけなら、Mock.Of<T>()の方が簡潔に使用できます。
    var target1Mock = new Mock<ITarget>();
    ITarget target1 = target1Mock.Object;
    
    ITarget target2 = Mock.Of<ITarget>();
    
  • プロパティやメソッドをモック化する際、new Mock<T>()は任意のタイミングで実装できますが、Mock.Of<T>()の場合は基本的に呼び出し時に実装します。多数のプロパティやメソッドをモック化する場合はnew Mock<T>()の方が便利です。
    Mock.Of<T>()に関して、引数で指定する不思議?なラムダ式はLINQを使った表現(LINQ to Mocks)です。Mock.Get()を使用して、後からモックオブジェクトの取得やSetup()を呼び出すこともできます。
    // new Mock<T>()によるプロパティ・メソッドのモック化
    var target1Mock = new Mock<ITarget>();
    target1Mock.Setup(o => o.StrProp).Returns("test");
    target1Mock.Setup(o => o.Add(2, 3)).Returns(5);
    ITarget target1 = target1Mock.Object;
    
    // Mock.Of<T>()によるプロパティ・メソッドのモック化(LINQ to Mocks)
    ITarget target2 = Mock.Of<ITarget>(o => 
        o.StrProp == "test" && o.Add(2, 3) == 5
    );
    
    // テスト
    Assert.Equal("test", target1.StrProp);
    Assert.Equal(5, target1.Add(2, 3));
    Assert.Equal("test", target2.StrProp);
    Assert.Equal(5, target2.Add(2, 3));
    
    // (参考)
    // モック化対象オブジェクトからモックオブジェクトの取得
    Mock<ITarget> target2Mock = Mock.Get(target2);
    target2Mock.Setup(o => o.Add(1, 2)).Returns(100);
    
    // テスト
    Assert.Equal("test", target2.StrProp);
    Assert.Equal(5, target2.Add(2, 3));
    Assert.Equal(100, target2.Add(1, 2));
    
  • 両者で作成される既定のモック化対象オブジェクトは微妙に異なるので注意が必要です。
    var target1Mock = new Mock<ITarget>();
    ITarget target1 = target1Mock.Object;
    
    ITarget target2 = Mock.Of<ITarget>();
    
    target1.StrProp = "test";
    Assert.Null(target1.StrProp); // 既定ではプロパティ値が保持されない
    
    target2.StrProp = "test";
    Assert.Equal("test", target2.StrProp);
    
    • new Mock<T>で作成されたモック化対象オブジェクトは、既定でプロパティが実装されていません。モック化対象オブジェクトのプロパティに値を設定しても保持されず、プロパティ値を読み取るとnullになります。
    • Mock.Of<T>()で作成されたモック化対象オブジェクトは、次のようにSetupAllProperties()で全てのプロパティが実装されています。モック化対象オブジェクトのプロパティに値が設定された場合、そのプロパティの値を後から取得することができます。詳細はGitHubのソースコードをご覧ください。
      public partial class Mock
      {
      	public static T Of<T>() where T : class
      	{
      		return Mock.Of<T>(MockBehavior.Default);
      	}
      	public static T Of<T>(MockBehavior behavior) where T : class
      	{
      		var mock = new Mock<T>(behavior);
      		if (behavior != MockBehavior.Strict)
      		{
      			mock.SetupAllProperties();
      		}
      		return mock.Object;
      	}
      






-.NET Core, 1. システムエンジニアリング, 実装技術

関連記事

Java/JavaEE開発キットの作成

Javaアプリ開発者のローカルPCに、ファイル展開するだけで開発環境をできるようにするための開発キットの準備について記載します。 ★随時更新予定★ 背景 Java/JavaEE等を使ったアプリ開発では …

Logicool MX Keys(KX800)でキー入力が遅延する

事象 次のようにデスクトップPC(Windows10)にUSBレシーバ+MX Keys(KX800)環境で、キー入力が遅延する事象が時々発生します。 ミリ秒レベルの若干の入力遅延がある。入力できないわ …

.NET Core(C#): xUnitのAssert使用方法

はじめに 次の環境を使用して動作確認しています。 OS Windows 10(64ビット) IDE Microsoft Visual Studio Community 2019(16.8.5) + C …

DOSバッチ(bat)の環境変数

ちょっとした事でbatファイルを作成することが多い。 そのたびにネット検索するのが非効率なため、リファレンス化しようと思う。 そういう目的なので、自分がよく調べる項目に絞っている。 開発時の注意点 直 …

.NET Core(C#): List・HashSetのContains性能比較

対象データが処理対象かの判定、データのユニーク化等の用途で、コレクション内のデータ存在チェックを行いたい場合があります。これを実現するために、List/Dictionary等のコレクションクラスのCo …