2012-06-12 11 views
24

obtuve una clase que obtiene por argumento un delegado. Esta clase invoca ese delegado, y quiero probarlo unitariamente con Moq. ¿cómo puedo verificar que se llamó este método?Verificando que un delegado fue llamado con Moq

clase de ejemplo:

public delegate void Foo(int number); 

public class A 
{ 
    int a=5; 

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

y quiero comprobar que Foo fue llamado. Gracias.

+3

Creo que necesita cambiar la respuesta aceptada, porque la respuesta de @Lukazoid es más correcta que la suya. –

+0

En el constructor, ¿la línea debe leer 'myFoo (a)'? Estás invocando esa instancia de 'Foo', no la clase' Foo' en sí, ¿verdad? –

Respuesta

28

¿Qué ocurre con el uso de una función anónima? Puede actuar como una burla en línea aquí, no necesita un marco de burla.

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

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

Moq no admite la burla de delegados. Pero puede crear alguna de las interfaces, con método, que coincide con su firma del delegado:

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

A continuación, cree simulacro, que implementa esta interfaz, y utilizar este objeto de burla para crear delegado:

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

Después de hacer ejercicio sut, usted podrá verificar las expectativas en su objeto burlado.

ACTUALIZACIÓN: en realidad puede simplemente pasar bar.Object.M a su sut, sin Foo creación de instancia delegado. Pero de todos modos, burlarse de los delegados requiere la creación de interfaz.

+0

Sólo un FYI, Moq ahora es compatible con la burla de los delegados ver mi respuesta y [aquí] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

3

Puede hacer algo así:

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

Desde Moq no soporta burlas delegados, por lo general va manejar esto con algo como:

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

donde el delegado proporcionado realiza alguna acción simple y verificable.

+1

Sólo un FYI, Moq ahora admite la burla de los delegados ver mi respuesta y [aquí] (https://github.com/Moq/moq4/commit/e614ae5b4a14896503b59e2a70ac799bb66e741b) – Lukazoid

32

A partir de this commit Moq ahora es compatible con la burla de los delegados, para su situación que lo haría así:

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

luego verificar el delegado se invocó:

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

O bien:

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