moq Mockは使えますか? インターフェースではなくクラスをモックするには?質問する

moq Mockは使えますか? インターフェースではなくクラスをモックするには?質問する

を通過するhttps://github.com/Moq/moq4/wiki/クイックスタート、インターフェースをモックしているのがわかります。

レガシー コードにインターフェイスを持たないクラスがあります。 を実行するとMock<MyClass>、次の例外が発生します。

追加情報: クラス MyCompnay.Mylegacy.MyClass のプロキシをインスタンス化できません。

Moq を使用してレガシーコードからクラスをモックするにはどうすればよいですか?

ベストアンサー1

それ具体的なクラスをモック化することが可能

[TestClass]
public class PlaceholderParserFixture
{

  public class Foo
  {
     public virtual int GetValue()
     {
        return 11;
     }
  }

  public class Bar
  {
     private readonly Foo _foo;

     public Bar(Foo foo)
     {
        _foo = foo;
     }

     public int GetValue()
     {
        return _foo.GetValue();
     }
  }

  [TestMethod]
  public void MyTestMethod()
  {
     var foo = new Mock<Foo>();
     foo.Setup(mk => mk.GetValue()).Returns(16);
     var bar = new Bar(foo.Object);

     Assert.AreEqual(16, bar.GetValue());
  }

}

しかし、

  • パブリッククラスである必要があります
  • モックするメソッドは仮想メソッドである必要があります

私が受け取ったメッセージ:

クラスを内部化する

Castle.DynamicProxy.Generators.GeneratorException: 型 MoqFixture+Foo はパブリックではありません。アクセスできない型のプロキシを作成することはできません。

または、非仮想メソッドを持つ

System.NotSupportedException: 非仮想 (VB でオーバーライド可能) メンバーのセットアップが無効です: mk => mk.GetValue()

メッセージと一致しないcannot instantiateので、何か他の問題があるようです。

モックオブジェクトにデフォルトコンストラクタがない場合、そのエラーメッセージが表示されることがあります。

例えば

public class Foo
{

    private int _value;
    public Foo(int value)
    {
       _value = value;
    }

    public virtual int GetValue()
    {
        return _value;
    }
}

Mock<> コンストラクタに値を渡すことでこれを回避できます。

例えば

var foo = new Mock<Foo>(MockBehavior.Strict, new object[] { 11 });

おすすめ記事