c# - parámetro - ¿Cómo puedo Moq un método que tiene un argumento opcional en su firma sin especificarlo explícitamente o usar una sobrecarga?
parametros opcionales mvc (2)
Acabo de encontrar este problema hoy, Moq no es compatible con este caso de uso. Entonces, parece que anular el método sería suficiente para este caso.
public interface IFoo
{
bool Foo(string a);
bool Foo(string a, bool b);
}
Ahora ambos métodos están disponibles y este ejemplo funcionaría:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
Dada la siguiente interfaz:
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Intentando burlarse usando Moq:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
produce el siguiente error en el tiempo de compilación:
Un árbol de expresiones no puede contener una llamada o invocación que use argumentos opcionales
He encontrado el problema anterior planteado como una enhancement en la lista de problemas de Moq y parece estar asignado a la versión 4.5 (siempre que sea).
Mi pregunta es: ¿qué debo hacer dado que lo anterior no se va a solucionar pronto? ¿Son mis opciones solo para establecer explícitamente el valor predeterminado del parámetro opcional cada vez que me burlo de él (lo que en cierto modo frustra el punto de especificar uno en primer lugar) o para crear una sobrecarga sin el bool (como lo hubiera hecho? antes de C # 4)?
¿O alguien ha encontrado una forma más inteligente de superar este problema?
Creo que su única opción ahora es incluir explícitamente el parámetro bool
en la configuración de Foo
.
No creo que derrote el propósito de especificar un valor predeterminado. El valor predeterminado es una conveniencia para el código de llamada, pero creo que debe ser explícito en sus pruebas. Digamos que podría dejar de especificar el parámetro bool
. ¿Qué sucede si, en el futuro, alguien cambia el valor predeterminado de b
a true
? Esto dará lugar a pruebas fallidas (y con razón), pero serán más difíciles de corregir debido a la suposición oculta de que b
es false
. Especificar explícitamente el parámetro bool
tiene otro beneficio: mejora la legibilidad de sus pruebas. Alguien que lo haga sabrá rápidamente que hay una función Foo
que acepta dos parámetros. Esa es mi 2 centavos, al menos :)
En cuanto a especificarlo cada vez que se burla de él, no duplique el código: cree y / o inicialice el simulacro en una función, para que solo tenga un único punto de cambio. Si realmente lo desea, puede superar el aparente cortocircuito de Moq aquí duplicando los parámetros de Foo
en esta función de inicialización:
public void InitFooFuncOnFooMock(Mock<IFoo> fooMock, string a, bool b = false)
{
if(!b)
{
fooMock.Setup(mock => mock.Foo(a, b)).Returns(false);
}
else
{
...
}
}