que - moq pcs
Usar moq para simular solo algunos métodos (3)
Ampliando la respuesta de Lee ,
No es necesario que todos los métodos y propiedades de su clase sean virtuales, solo los que desea simular.
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 predeterminado, también necesitará especificar argumentos para pasar a través de:
var mock = new Mock<YourTestClass>(x, y, z);
// or
var mock = new Mock<YourTestClass>(MockBehavior.Default, x, y, z);
Donde x, y, z
son los primeros, segundos y terceros parámetros para su constructor, respectivamente.
Y, por último, si el método que está buscando para burlarse está protegido, deberá incluir Moq.Protected
using Moq.Protected;
TReturnType returnValue = default(TReturnType);
mock.Protected()
.Setup<TReturnType>("YourMockMethodName", It.IsAny<int>()) // methodname followed by arguments
.Returns(returnValue);
Tengo el siguiente método:
public CustomObect MyMethod()
{
var lUser = GetCurrentUser();
if (lUser.HaveAccess)
{
//One behavior
}
else
{
//Other behavior
}
//return CustomObject
}
Quiero burlar IMyInterface.GetCurrentUser
, para que al llamar a MyMethod
pueda acceder a una de las rutas de código para verificarlo. ¿Cómo hacer eso con Moq?
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, lResult
siempre es null
y cuando intento acceder a MyMethod
en depuración, siempre salteo a la siguiente declaración.
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. Suponiendo que esto no sea un problema, puede escribir una prueba como esta:
var mock = new Mock<YourTestClass>();
mock.CallBase = true;
mock.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser);
mockedTest.Object.MyMethod();
Tuve un caso similar. Encontré que el siguiente código me daba más flexibilidad para usar tanto los métodos simulados como los métodos reales de alguna 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 usar el método real, pero también usar cosas como Verificar para ver cuántas veces se ha llamado.