66

モック内のメソッドが期待されるオブジェクトパラメータで呼び出されていることを確認しようとしています。私はMoq、nUnitを使用していて、AutoFixtureのLikenessが仕事を成し遂げるべきだと考えています。以下は私がやろうとしていることの簡略版です。

AutoFixtureでこれを行う方法はありますか?Something適切なパラメータで呼び出されたことを確認するためのより良い方法はありますか?

クラス内のEqualsをオーバーライドしAてプロパティ値を比較し、Verify行を次のように変更します。

barMock.Verify(m => m.Something(a));

パスしますが、プロジェクトのAのようなすべてのクラスでEqualsをオーバーライドしたくありません。

namespace Test
{
    using Moq;
    using NUnit.Framework;
    using Ploeh.SemanticComparison.Fluent;

    public class A
    {
        public int P1 { get; set; }
    }
    public interface IBar
    {
        void Something(A a);
    }

    public class Foo
    {
        public A Data { get; private set; }
        public void DoSomethingWith(IBar bar)
        {
            Data = new A { P1 = 1 };
            bar.Something(Data);
        }
    }

    [TestFixture]
    public class AutoFixtureTest
    {
        [Test]
        public void TestSample()
        {
            var foo = new Foo();
            var barMock = new Mock<IBar>();
            var a = new A { P1 = 1 };
            var expectedA = a.AsSource().OfLikeness<A>();

            foo.DoSomethingWith(barMock.Object);

            expectedA.ShouldEqual(foo.Data);   // passes
            barMock.Verify(m => m.Something(expectedA.Value));  // fails
        }
    }
}
4

2 に答える 2

111

Moqでは、デフォルトで引数の参照の同等性をチェックするため、テストと実装でVerify同じインスタンスを提供した場合にのみ合格します(オーバーライドした場合を除く)。Equals

あなたの場合、はテストで作成されたものをexpectedA.Value返すだけですnew A { P1 = 1 }が、もちろん、で作成されたものと同じインスタンスではありませんDoSomethingWith

MoqのIt.Is構成を使用して、オーバーライドせずにこれを適切にテストする必要がありますEquals(実際、これにはAutofixtureはまったく必要ありません)。

barMock.Verify(m => m.Something(It.Is<A>(arg => arg.P1 == a.P1)));

ただし、P1、P2、P3などの複数のプロパティがある場合は...AutoFixtureが便利です。

barMock.Verify(m => m.Something(It.Is<A>(arg => expectedA.Equals(a))));

すべてのプロパティの同等性チェックを手動で書き出す必要がないためです。

于 2012-01-16T20:15:30.247 に答える
5

AutoFixture 2.9.1(またはそれ以降)にアップグレードする場合は、LikenessインスタンスでCreateProxyメソッドを呼び出すことができます。これにより、宛先タイプの動的プロキシが発行されます。

生成された動的プロキシは、構文を単純化するLikenessを使用してEqualsをオーバーライドします(かなり多く)。

Likenessプロキシを使用するように変更された元のテスト方法は次のとおりです。

[Test]
public void TestSample()
{
    var foo = new Foo();
    var barMock = new Mock<IBar>();
    var expected = new A().AsSource().OfLikeness<A>().CreateProxy();
    expected.P1 = 1;

    foo.DoSomethingWith(barMock.Object);

    Assert.True(expected.Equals(foo.Data));     // passes
    barMock.Verify(m => m.Something(expected)); // passes
}

また、 Anyインスタンスを受け入れるよりも、テストアサーションがはるかに具体的になることに注意してください。

この新機能の詳細については、こちらをご覧ください

于 2012-02-20T15:51:03.737 に答える