2012-01-16 12 views
30

Estoy intentando verificar que se llame a un método dentro de una simulación con un parámetro de objeto esperado. Estoy usando Moq, nUnit y pensando que la semejanza de AutoFixture debería hacer el trabajo. A continuación se muestra una versión simplificada de lo que estoy tratando de hacer.Uso de Verificar para confirmar los valores de los parámetros esperados en la clase simulada de Moq

¿Hay alguna manera de hacer esto con AutoFixture? ¿Hay una mejor manera de verificar que se llame al Something con el parámetro apropiado?

Anulación es igual en la clase A para comparar los valores de las propiedades y cambiar la línea Verify a:

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

pases, sin embargo yo prefiero no sobrescribe equals 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 
     } 
    } 
} 

Respuesta

45

En el Verify Moq mediante comprobaciones de referencia por defecto para la igualdad de los argumentos por lo que sólo pasa cuando nos proporcione los mismos casos (excepto si se ha anulado Equals) en sus análisis y en su aplicación.

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

Es necesario utilizar It.Is construcción de Moq para probar adecuadamente esto sin anulando Equals (de hecho, para este que no es necesario Autofixture en absoluto):

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

Pero si tiene varias propiedades como P1, P2 , P3 ... AutoFixture puede ser útil:

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

Debido a que no es necesario escribir las comprobaciones eqaulity manualmente para todas las propiedades.

+2

+1 En particular, la última solución es el enfoque correcto con Semejanza. FWIW hay un elemento de trabajo para una nueva funcionalidad de Likeness que le permite emitir dinámicamente un proxy que anula Equals, lo que simplificaría en gran medida la sintaxis anterior: http://autofixture.codeplex.com/workitem/4230 –

+0

Eso lo hizo, gracias ! – jaminto

5

Si actualiza a AutoFixture 2.9.1 (o posterior) 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 el uso de Igualdad que simplifica la sintaxis (bastante).

Aquí es el método de ensayo original, modificado para utilizar el proxy Objeto:

[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 la afirmación de prueba mucho más específico que aceptar Cualquier instancia.

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

Cuestiones relacionadas