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. システムエンジニアリング, 実装技術

関連記事

おすすめキーボード: MX Keys(KX800)レビュー

キーが浅く指の移動が最小限で抑えられ、多少打鍵位置がずれても正確に押せるので、入力がとても楽で、肩こりや首の痛みが軽減されました。また、在宅勤務用PCや副業用PC等の複数PCの切り替えをキーボードから …

Java/JavaEE開発キットの作成

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

.NET Core(C#): MoqのSetupProperty()/SetupGet()/SetupSet()の違い

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

slf4jで独自ログ項目を追加(MDC)

はじめに 業務要件、障害発生時の処理追跡や証跡等、ログ出力に特定項目を含めたい場合があります。 共通のログ出力ユーティリティやライブラリを作って、その中でログ出力内容を変更しても良いのですが、MDC( …

mavenマルチモジュールプロジェクトの構成例

システム開発でよく使用するmavenマルチモジュールプロジェクトの構成サンプルを説明します。 構成方針 複数のサブシステムをもつシステム開発を想定しています。システム名はzzz、サブシステムはf10, …