3

単体テストに Moq フレームワークを使用していますが、この興味深い問題に遭遇しました。

public interface Bar : IEquatable<Bar>
{
}

[TestClass]
public class TestClass
{
    Mock<Bar> a;
    Mock<Bar> b;

    public TestClass()
    {
        a = new Mock<Bar>();
        b = new Mock<Bar>();

        a.Setup(bar => bar.Equals(b.Object)).Returns(true);
    }

    [TestMethod]
    public void AssertEqualsTest()
    {
        Assert.AreEqual(a.Object, b.Object); //fails
    }

    [TestMethod]
    public void AssertIsTrueTest()
    {
         Assert.IsTrue(a.Object.Equals(b.Object)); //passes
    }
}

創刊

だからAssert.AreEqual失敗するだけです。クラスのほとんど (すべてではないにしても) が IEquatable を継承しているにもかかわらず、等価性をチェックする必要があるたびに 2 番目のテストの行を使用する必要はありません。

Assert.AreEqualSetup が IEquality.Equals() 関数 (おそらくチェックしない) のみを設定しているため、失敗したと思うかもしれませんが、次の行を追加すると、

a.Setup(x => x.Equals((object)b.Object)).Returns(true);

コンストラクターに対して、それはまだ失敗します。

第二号

: IEquatable<Bar>インターフェイス宣言からをコメントアウトすると( がa.Setup上書きされるようにobject.Equals)、両方のテストが失敗します。

私の望む結果は、Mockオブジェクトに equals を設定して を呼び出すことができるようにすることAssert.AreEqualです。

4

2 に答える 2

2

私は..

mockLine2.CallBase = True

なぜ?

注文サービスをテストしています。注文には 2 つの明細があるため、サービスはいくつかの基準に一致する明細を削除します。行は IList であり、List (など) は .equals() を使用して必要な項目を見つけるため、行を削除するには、渡す equals の実装が必要です。

Assert.IsTrue(mockLine2.Object.Equals(mockLine2.Object)

「Moq モックは行がそれ自体に等しいことを検出していないため、注文の行コレクションは行を見つけることができません。」)

Order はテスト対象のクラスではないため、順序をモックorder.Lines.Remove()し、正しい行で呼び出されていることをアサートする必要があると主張することもできますが、実際のドメイン オブジェクトを使用する方が実際のドメイン オブジェクトを使用する方が苦労が少ないことがわかりました (それらはすべて公平です)。それらを嘲笑するよりも。

于 2012-09-19T10:23:07.800 に答える