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

関連記事

.NET Core: Microsoft.Graph.Authの正式版予定

.NET CoreでMicrosoft Graphを操作するために、Microsoft Graph API SDK(“Microsoft.Graph”パッケージ)の使用を考えて …

DB操作フレームワーク はJPA or mybatis?

開発に向けた準備で、開発標準を準備するフレームワーク(FW)チーム、それらを使って実装を行う業務チームが集まって、「DB操作を行うためのFWは何を使うか?」という協議になった。 FWチームは、FW・J …

デジタル証明書のエンコードと拡張子の違い

デジタル証明書の種類と拡張子の理解が曖昧だったので整理してみました。 証明書や鍵そのものは基本的にはバイナリデータです。 これらのデータは、X.509やPKCSで仕様化されています。 X.509: 公 …

ルートCA、サーバ・クライアント証明書の作成方法

概要 検証・開発環境での使用を前提とした、ルートCA証明書の作成、その証明書で署名したサーバ証明書とクライアント証明書を作成する手順を説明します。 可能な限りシンプルで簡単な条件・手順になっています。 …

Windows10で開発・検証用のプロキシサーバを構築

本番環境でプロキシを介して通信を行うアプリを開発したいが、開発環境ではプロキシがない… そんな時のためにローカルに検証用のプロキシサーバを構築してみます。 概要 Windows 10(64 …