Tengo una prueba unitaria donde tengo que burlarme de un método no virtual que devuelve un tipo bool
public class XmlCupboardAccess
{
public bool IsDataEntityInXmlCupboard(string dataId,
out string nameInCupboard,
out string refTypeInCupboard,
string nameTemplate = null)
{
return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
}
}
Así que tengo un objeto simulado de XmlCupboardAccess
clase y estoy tratando de configurar simulacro para este método en mi caso de prueba como se muestra a continuación
[TestMethod]
Public void Test()
{
private string temp1;
private string temp2;
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
_xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false);
//exception is thrown by this line of code
}
Pero esta línea arroja una excepción.
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
¿Alguna sugerencia de cómo evitar esta excepción?
c#
unit-testing
moq
Rahul Lodha
fuente
fuente
XmlCupboardAccess
?virtual
. Moq no puede burlarse de un tipo concreto que no puede anular.Respuestas:
Moq no puede burlarse de métodos no virtuales y clases selladas. Mientras ejecuta una prueba usando un objeto simulado, MOQ realmente crea un tipo de proxy en memoria que hereda de su "XmlCupboardAccess" y anula los comportamientos que ha configurado en el método "SetUp". Y como sabe en C #, puede anular algo solo si está marcado como virtual, que no es el caso con Java. Java asume que cada método no estático es virtual por defecto.
Otra cosa que creo que deberías considerar es introducir una interfaz para tu "CupboardAccess" y comenzar a burlarte de la interfaz. Le ayudaría a desacoplar su código y obtener beneficios a largo plazo.
Por último, hay marcos como: TypeMock y JustMock que funcionan directamente con el IL y, por lo tanto, pueden burlarse de métodos no virtuales. Sin embargo, ambos son productos comerciales.
fuente
Como ayuda para cualquiera que tuviera el mismo problema que yo, accidentalmente escribí mal el tipo de implementación en lugar de la interfaz, por ejemplo
en vez de
fuente
Por favor, vea ¿ Por qué la propiedad que quiero burlar debe ser virtual?
Es posible que deba escribir una interfaz de contenedor o marcar la propiedad como virtual / abstracta ya que Moq crea una clase proxy que utiliza para interceptar llamadas y devolver los valores personalizados que puso en la
.Returns(x)
llamada.fuente
En lugar de burlarse de la clase concreta, debe burlarse de esa interfaz de clase. Extraer interfaz de la clase XmlCupboardAccess
Y en lugar de
cambiar a
fuente
También obtendrá este error si está verificando que se llama a un método de extensión de una interfaz.
Por ejemplo, si te estás burlando:
Obtendrá la misma excepción porque
.ValidateAndThrow()
es una extensión en laIValidator<T>
interfaz.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
fuente
Código:
Pero ver excepción.
fuente