Использование Verify для подтверждения ожидаемых значений параметров в классе Moq mock - PullRequest
44 голосов
/ 16 января 2012

Я пытаюсь проверить, что метод в макете вызывается с ожидаемым параметром объекта. Я использую Moq, nUnit и думаю, что сходство с AutoFixture должно быть выполнено. Ниже приведена упрощенная версия того, что я пытаюсь сделать.

Есть ли способ сделать это с помощью AutoFixture? Есть ли лучший способ убедиться, что Something вызывается с соответствующим параметром?

Переопределение Equals в классе A для сравнения значений свойств и изменения строки Verify на:

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

проходит, однако я бы не стал переопределять Equals в каждом классе, подобном A, в моем проекте.

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
        }
    }
}

Ответы [ 2 ]

69 голосов
/ 17 января 2012

В Verify Moq по умолчанию проверяет равенство ссылок для аргументов, поэтому оно проходит только тогда, когда вы предоставляете одинаковые экземпляры (кроме случаев, когда вы переопределили Equals) в ваших тестах и ​​в вашей реализации.

В вашем случае expectedA.Value просто возвращает new A { P1 = 1 }, созданный в тесте, что, конечно, не тот же экземпляр, созданный в DoSomethingWith.

Вам необходимо использовать It.Is конструкцию Moq, чтобы правильно проверить это без переопределения Equals (фактически для этого вам вообще не нужно автофиксирование):

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))));

Поскольку вам не нужно выписывать проверки eqaulity вручную для всех свойств.

5 голосов
/ 20 февраля 2012

Если вы обновитесь до AutoFixture 2.9.1 (или новее), вы можете вызвать метод CreateProxy в экземпляре Likeness, который будет генерировать динамический прокси для целевого типа.

Сгенерированный динамический прокси переопределяет Equals с использованием Likeness, что упрощает синтаксис (довольно много).

Вот оригинальный метод тестирования, модифицированный для использования прокси-сервера 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
}

Обратите внимание, что это также делает тестовое утверждение гораздо более конкретным, чем принятие любого экземпляра.

Подробнее об этой новой функции можно узнать здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...