2012-01-16 12 views
30

Sto provando a verificare che un metodo all'interno di una simulazione venga chiamato con un parametro oggetto previsto. Sto usando Moq, nUnit, e penso che la somiglianza di AutoFixture dovrebbe portare a termine il lavoro. Di seguito è una versione semplificata di quello che sto cercando di fare.Utilizzo di Verifica per confermare i valori dei parametri previsti nella classe Mock Moq

C'è un modo per farlo con AutoFixture? C'è un modo migliore per verificare che Something venga chiamato con il parametro appropriato?

Override Equals nella classe A per confrontare i valori delle proprietà e cambiando la linea Verify a:

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

passaggi, però preferirei non sovrascrive equals in ogni classe come A nel mio progetto.

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

risposta

45

Nel Verify Moq da controlli predefiniti riferimento uguaglianza per gli argomenti in modo che passi solo quando si forniscono le stesse istanze (tranne se hai sovrascritta Equals) nei test e nell'implementazione.

Nel caso in cui il expectedA.Value restituisca appena il creato nel test, che ovviamente non è la stessa istanza creata in DoSomethingWith.

è necessario utilizzare It.Is costrutto di Moq per testare correttamente questo senza ignorando Equals (infatti per questo non è necessario Autofixture affatto):

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

Ma se si dispone di più immobili come P1, P2 , P3 ... AutoFixture può essere utile:

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

Perché non c'è bisogno di scrivere i controlli eqaulity manualmente per tutte le proprietà.

+2

+1 In particolare, l'ultima soluzione è l'approccio corretto con Likeness. FWIW c'è un elemento di lavoro per una nuova funzionalità per Likeness che consente di emettere dinamicamente un proxy che esegue l'override di Equals, il che semplificherebbe enormemente la sintassi precedente: http://autofixture.codeplex.com/workitem/4230 –

+0

Questo l'ha fatto, grazie ! – jaminto

5

Se si esegue l'aggiornamento a AutoFixture 2.9.1 (o successivo) è possibile chiamare il metodo CreateProxy nell'istanza Likeness che emetterà un proxy dinamico per il tipo di destinazione.

Il proxy dinamico generato esegue l'override di Equals usando Likeness che semplifica la sintassi (piuttosto molto).

Ecco il metodo di prova originale, modificati per utilizzare il proxy Figura:

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

Nota che rende anche l'affermazione di prova molto più specifico che accettare Qualsiasi esempio.

È possibile trovare ulteriori dettagli su questa nuova funzione here.

Problemi correlati