2011-01-22 20 views
40

tengo el siguiente método:moq burlarse sólo algunos métodos

public CustomObect MyMethod() 
{ 
    var lUser = GetCurrentUser(); 
    if (lUser.HaveAccess) 
    { 
     //One behavior 
    } 
    else 
    { 
     //Other behavior 
    } 

    //return CustomObject 
} 

Quiero burlarse IMyInterface.GetCurrentUser, por lo que, si bien llamando MyMethod que pudiera llegar a una de las rutas de código para comprobarlo. ¿Cómo hacer eso con Moq?

que estoy haciendo lo siguiente:

var moq = new Mock<IMyInterface>();    
moq.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser); 

//act 
var lResult = moq.Object.MyMethod(); 

Pero por alguna razón siempre es lResultnull y cuando estoy tratando de entrar en MyMethod de depuración Siempre estoy saltando a la siguiente instrucción.

+0

¿Dónde tiene inicializado 'lUnauthorizedUser'? Me imagino que querrías algo como 'moq.Setup (x => x.GetCurrentUser()). Devuelve (new User() {HaveAccess = false});' –

+0

Tyler, seguro que lo estoy configurando en el código anterior , simplemente no lo pegó para mantener el código corto. –

Respuesta

83

Esto se llama simulacro parcial y la forma en que sé hacerlo en moq requiere burlar la clase en lugar de la interfaz y luego establecer la propiedad "Callbase" en su objeto simulado en "verdadero".

Esto requerirá que todos los métodos y propiedades de la clase que está probando sean virtuales. Asumiendo que esto no es un problema, se puede entonces escribir una prueba como esta:

var mock = new Mock<YourTestClass>(); 
mock.CallBase = true; 
mock.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser); 
mockedTest.Object.MyMethod(); 
+0

¡Impresionante! Muchas gracias, no creo que sea así de simple. –

+0

funcionan como un encanto !!! –

11

Ampliando lee's answer,

No es necesario que realice todos los métodos y propiedades de la clase virtual, sólo se aquellos a los que te quieres burlar.

Además, debe tenerse en cuenta que debe burlarse de la implementación concreta de su clase.

var mock = new Mock<YourTestClass>(); // vs. var mock = new Mock<IYourTestInterface>();

Si su clase no tiene un constructor por defecto, también tendrá que especificar argumentos para transmitir a ella a través de:

var mock = new Mock<YourTestClass>(x, y, z); 
// or 
var mock = new Mock<YourTestClass>(MockBehavior.Default, x, y, z); 

Dónde x, y, z son el primer, segundo y tercer parámetros a su constructor respectivamente.

Y por último, si el método que busca burlarse está protegido tendrá que incluir Moq.Protected

using Moq.Protected; 

TReturnType returnValue = default(TReturnType); 

mock.Protected() 
    .Setup<TReturnType>("YourMockMethodName", It.IsAny<int>()) // methodname followed by arguments 
    .Returns(returnValue); 
+0

Vale la pena señalar que puede usar 'nameof (YourTestClass.YourMockMethodName)' en lugar de "YourMockMethodName". Debido a esto, cuando refactorice el nombre del método, la prueba seguirá funcionando. – Shoter

4

tuve un caso similar. He encontrado el siguiente código me dio más flexibilidad para utilizar ambos métodos burlado y métodos actuales de algunas implementación específica de una interfaz:

var mock = new Mock<ITestClass>(); // Create Mock of interface 

// Create instance of ITestClass implementation you want to use 
var inst = new ActualTestClass(); 

// Setup to call method of an actual instance 
// if method returns void use mock.Setup(...).Callback(...) 
mock.Setup(m => m.SomeMethod(It.IsAny<int>()) 
    .Returns((int x) => inst.SomeMethod(x)); 

Ahora puede utilizar el método real, sino también usar cosas como Verify para ver cuántas veces ha sido llamado.

+0

Ese señor ... es un trabajo interesante: D – ppumkin

Cuestiones relacionadas