2012-06-12 17 views
24

Ho ottenuto una classe che ottiene argomento un delegato. Questa classe richiama quel delegato e voglio testarlo unitamente a Moq. come posso verificare che questo metodo sia stato chiamato?Verificare che un delegato sia stato chiamato con Moq

esempio di classe:

public delegate void Foo(int number); 

public class A 
{ 
    int a=5; 

    A (Foo myFoo) 
    { 
     Foo(a); 
    } 
} 

e voglio verificare che Foo è stato chiamato. Grazie.

+3

Penso che devi cambiare la risposta accettata, perché la risposta di @Lukazoid è più giusta della tua scelta. –

+0

Nel costruttore, la riga dovrebbe leggere 'myFoo (a)'? Stai invocando quell'istanza di 'Foo', non la classe' Foo' stessa, giusto? –

risposta

28

Che dire dell'utilizzo di una funzione anonima? Può comportarsi come un finto in linea qui, non è necessario un quadro di derisione.

bool isDelegateCalled = false; 
var a = new A(a => { isDelegateCalled = true}); 

//do something 
Assert.True(isDelegateCalled); 
3

Moq non supporta i delegati di derisione. Ma si può creare una certa interfaccia, con metodo, che corrisponde alla firma del delegato:

public interface IBar 
{ 
    void M(int number); 
} 

Poi creare finto, che implementa questa interfaccia, e utilizzare questo oggetto fittizio per creare delegato:

Mock<IBar> bar = new Mock<IBar>(); 
Foo foo = new Foo(bar.Object.M); 
A a = new A(foo); 
bar.Verify(x => x.M(5)); 

Dopo l'esercizio il tuo sut, sarai in grado di verificare le aspettative sul tuo oggetto deriso.

AGGIORNAMENTO: In realtà è sufficiente passare bar.Object.M al proprio sut, senza creazione dell'istanza delegato Foo. Ma comunque, i delegati di derisione richiedono la creazione di interfacce.

+0

Solo una FYI, Moq ora supporta la presa in giro dei delegati vedere la mia risposta e [qui] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

3

Si può fare qualcosa di simile:

public interface IWithFOOMethod 
{ 
    void FooAlikeMethod(int number); 
} 

Mock<IWithFOOMethod> myMock = new Mock<IWithFOOMethod>(); 

A a = new A(myMock.Object.FooAlikeMethod); 

myMock.Verify(call => call.Foo(It.IsAny<int>()), Times.Once()) 
1

Dato Moq non supporta beffardo delegati, io di solito gestire questo con qualcosa di simile:

var list = new List<int>(); 
var del = i => list.Add (i); 
var a = new A(del); 
list.ShouldContainOnly (new[] { 5 }); 

in cui il delegato previsto esegua alcune azione semplice e verificabile.

+1

Solo una FYI, Moq ora supporta la presa in giro dei delegati vedere il mio rispondi e [qui] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

32

A partire dal this commit Moq ora supporta la beffarda dei delegati, per la vostra situazione si farebbe in questo modo:

var fooMock = new Mock<Foo>(); 
var a = new A(fooMock.Object); 

Quindi è possibile verificare il delegato è stato invocato:

fooMock.Verify(f => f(5), Times.Once); 

Oppure:

fooMock.Verify(f => f(It.IsAny<int>()), Times.Once); 
Problemi correlati