Usando Verificar para confirmar los valores de parámetros esperados en la clase MOQ Mock

StackOverflow https://stackoverflow.com/questions/8883685

  •  29-10-2019
  •  | 
  •  

Pregunta

Estoy tratando de verificar que se llama un método dentro de un simulacro con un parámetro de objeto esperado. Estoy usando MOQ, Nunit y pensando que la semejanza de la autofixture debería hacer el trabajo. A continuación se muestra una versión simplificada de lo que estoy tratando de hacer.

¿Hay alguna forma de hacer esto con la autofixture? ¿Hay una mejor manera de verificar que Something se llama con el parámetro apropiado?

Anular iguales en el A clase para comparar los valores de la propiedad y cambiar el Verify línea a:

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

Pases, sin embargo, prefiero no anular iguales en cada clase como A en mi proyecto.

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
        }
    }
}
¿Fue útil?

Solución

En el Verify MOQ, por defecto, verifica la igualdad de referencia para los argumentos, por lo que solo pasa cuando proporciona las mismas instancias (excepto si ha anulado Equals) en sus pruebas y en su implementación.

En tu caso el expectedA.Value Solo devuelve el new A { P1 = 1 } creado en la prueba, que por supuesto es la misma instancia creada en DoSomethingWith.

Necesitas usar moq's It.Is construir para probar correctamente esto sin anular Equals (De hecho, para esto no necesitas autofixture en absoluto):

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

Pero si tiene múltiples propiedades como P1, P2, P3 ... La enfoque automática puede ser útil:

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

Porque no necesita escribir las verificaciones de eqaulidad manualmente para todas las propiedades.

Otros consejos

Si se actualiza a la autofixture 2.9.1 (o más nueva), puede llamar al método CreateProxy en la instancia de semejanza que emitirá un proxy dinámico para el tipo de destino.

El proxy dinámico generado anula es igual a la imagen que simplifica la sintaxis (bastante).

Aquí está el método de prueba original, modificado para usar el proxy de imagen:

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

Tenga en cuenta que también hace que la afirmación de la prueba sea mucho más específica que aceptar Ningún instancia.

Puede encontrar más detalles sobre esta nueva característica. aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top