3

次のようなオブジェクトを渡すテストがあります。

var repo = new ActualRepo();

var sut = new Sut(repo);

私のテストでは、Repo には実際に実行する必要があるメソッドが 1 つありますが、別のメソッドはモックアウトして実行しないでください。

たとえば、次の疑似コードを見てみましょう。

var repo = new Mock<IRepo>();

repo.Setup(m => m.MethodIWantToCall()).WillBeExecuted();
repo.Setup(m => m.MethodIWantToMock()).Returns(false);

Moqを使用して、これは可能ですか?どのように行うことができますか?

編集:私は過去に TypeMock を使用しましたが、次のようなことができます。

Isolator.When(() => repo.MethodToIgnore()).WillBeIgnored();
Isolator.When(() => repo.MethodToActuallyRun()).WillBeExecuted();
4

2 に答える 2

5

これが有用かどうかという質問からはあまりわかりませんが、モックしたいメソッドが仮想である場合、オブジェクトを部分的にモックすることは可能です。

public class Foo {
    public string GetLive() {
        return "Hello";
    }

    public virtual string GetMock() {
        return "Hello";
    }
}

public class Snafu {
    private Foo _foo;
    public Snafu(Foo foo) {
      _foo = foo;
    }

    public string GetMessage() {
        return string.Format("{0} {1}", _foo.GetLive(), _foo.GetMock());
    }
}


[TestMethod]
public void NotMocked() {
    var snafu = new Snafu(new Foo());
    Assert.AreEqual("Hello Hello", snafu.GetMessage());
}


[TestMethod]
public void Mocked() {

    var mockFoo = new Mock<Foo>();
    mockFoo.Setup(mk => mk.GetMock()).Returns("World");

    var snafu = new Snafu(mockFoo.Object);

    Assert.AreEqual("Hello World", snafu.GetMessage());
}
于 2012-09-27T15:26:40.087 に答える
3

メソッドの1つが仮想であり、モックをインターフェイスではなくタイプに基づいていない限り、同じオブジェクトを使用する場合、Moqでこれを行うことはできません。

これは、インターフェイスに基づいてモック オブジェクトを渡す場合、実際のオブジェクトを渡していないため、オブジェクトの実際のメソッドにアクセスできないためです。

応答するように設定されているメソッドに応答する動的プロキシを渡しています。

TypeMock はこれを実現するために実行時にアセンブリを書き換えると思いますが、Moq は絶対にそうしません。

Moq で同様の結果を得たい場合:

  • 両方の方法をモックできます
  • 一方の依存関係をモックし、他方の依存関係をモックしないように、両方のメソッドを異なる依存関係に抽出する必要があります。
  • モックする必要があるメソッドを仮想にすることができます。これは、私が好むソリューションです。

編集AlanTの回答を読んだ後、回答を正確に編集しました。

于 2012-09-27T12:46:12.447 に答える