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

関連記事

VULTR: SSH鍵の作成とVPSの構築

VULTRでVPSを作成し、Tera Term(SSH)で管理する方法について説明します。 概要 VULTRにおいて、次の前提でVPSを構築する手順を説明します。 “New York(NJ …

Javaでサポートする暗号化アルゴリズム

Java暗号化アーキテクチャ Javaで暗号化処理を実装する場合、Java暗号化アーキテクチャ(Java Cryptography Architecture: JCA)と呼ばれるフレームワークを使いま …

ASP.NET Core: 変更ページを実行環境に反映

ASP.Net Core(3.0)の開発で、ページ(cshtml)を編集しながらページデザインを確認したい。 既定ではページを変更しても実行環境に反映れずサーバの再起動が必要となり開発効率が悪い。 サ …

PowerPointの削除できない個人情報を消す

PowerPointで「個人情報の削除」を実行するとこで、作成者や会社名等の個人情報を削除できます。しかしながら、特定の項目に入った個人情報については、PowerPointやWindowsの標準機能で …

.NET Core(C#): enumの使い方サンプル

はじめに サンプルは.NET Core 3.1 + C# 8.0で動作確認しています。 完全なソースコードはこちらで公開しています。 enumは基本的には数値型を保持しますが、文字列を保持したい場合は …