Использование Verify для подтверждения ожидаемых значений параметров в классе Moq mock
Я пытаюсь проверить, что метод внутри mock вызывается с ожидаемым параметром объекта. Я использую Moq, nUnit и думаю, что AutoFixture Likeness должен выполнить свою работу.
Ниже приведен упрощенный вариант того, что я пытаюсь сделать.
Есть ли способ сделать это с помощью AutoFixture? Есть ли лучший способ проверить, что Something
вызывается с соответствующим параметром?
Переопределение равных в классе 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
}
}
}
Ответы
Ответ 1
В Verify
Moq по умолчанию проверяет ссылочное равенство для аргументов, поэтому оно проходит только тогда, когда вы предоставляете те же экземпляры (кроме случаев, когда вы переопределяете 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))));
Поскольку вам не нужно вручную выставлять проверки eqaulity для всех свойств.
Ответ 2
Если вы обновляетесь до 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
}
Обратите внимание, что это также делает утверждение теста более конкретным, чем принятие любого экземпляра.
Подробнее об этой новой функции можно найти .