c# - Moq+Unit Testing-System.Reflection.TargetParameterCountException: desajuste de la cuenta de parĂ¡metros
wpf unit-testing (4)
En mi caso, pensé que el tipo de Returns<>
es el tipo de salida, pero de hecho era el tipo de entrada (s).
Entonces, si tienes un método
public virtual string Foo(int a, int b) { ... }
La cláusula correcta es .Returns<int, int>(...)
, NOT .Returns<string>(...)
que es lo que pensé inicialmente.
Mi error fue porque estaba probando una función con la misma entrada y tipo de retorno inicialmente, por ejemplo, public virtual string Foo(string a)
.
Estoy tratando de usar una lambda con una función de parámetros múltiples, pero Moq arroja esta excepción en el tiempo de ejecución cuando intento llamar a la mock.Object.Convert(value, null, null, null);
línea.
System.Reflection.TargetParameterCountException: Parameter count mismatch
El código es:
var mock = new Mock<IValueConverter>();
mock.Setup(conv => conv.Convert(It.IsAny<Object>(), It.IsAny<Type>(),
It.IsAny<Object>(), It.IsAny<CultureInfo>())).Returns((Int32 num) => num + 5);
var value = 5;
var expected = 10;
var actual = mock.Object.Convert(value, null, null, null);
¿Cuál es la forma correcta de implementarlo?
Es su cláusula de Returns
. Tienes un método de 4 parámetros que estás configurando, pero solo estás usando un parámetro lambda 1. Ejecuté lo siguiente sin problema:
[TestMethod]
public void IValueConverter()
{
var myStub = new Mock<IValueConverter>();
myStub.Setup(conv => conv.Convert(It.IsAny<object>(), It.IsAny<Type>(), It.IsAny<object>(), It.IsAny<CultureInfo>())).
Returns((object one, Type two, object three, CultureInfo four) => (int)one + 5);
var value = 5;
var expected = 10;
var actual = myStub.Object.Convert(value, null, null, null);
Assert.AreEqual<int>(expected, (int) actual);
}
Sin excepciones, pasó la prueba.
No es una respuesta para OP, pero tal vez para futuros usuarios de Google:
Recibí una Callback
que no coincide con la firma del método que se está configurando
Mock
.Setup(r => r.GetNextCustomerNumber(It.IsAny<int>()))
.Returns(AccountCounter++)
.Callback<string, int>(badStringParam, leadingDigit =>
{
// Doing stuff here, note that the ''GetNextCustomerNumber'' signature is a single int
// but the callback unreasonably expects an additional string parameter.
});
Este fue el resultado de algunas refactorizaciones y la herramienta de refactorización, por supuesto, no pudo darse cuenta de que la firma de Callback
era incorrecta.
Quizás es porque está pasando null
pero It.IsAny<Object>()
está esperando cualquier object
excepto null
? ¿Qué sucede si haces lo siguiente ?:
var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);
Esto es solo una puñalada en la oscuridad de mi parte, estoy más familiarizado con Rhino.Mocks.
Mi segunda suposición:
Después de mirar el Moq.chm que viene con la descarga,
Está utilizando el método de Setup(Expression<Action<T>>)
que "Especifica una configuración en el tipo de imitación para una llamada a un método de void
".
Desea el Setup<TResult>(Expression<Func<T,TResult>>)
que "Especifique una configuración en el tipo Setup<TResult>(Expression<Func<T,TResult>>)
para una llamada a un método de devolución de valor".
Entonces podrías probar:
mock.Setup<Int32>(
conv => {
conv.Convert(
It.IsAny<Object>(),
It.IsAny<Type>(),
It.IsAny<Object>(),
It.IsAny<CultureInfo>());
return num + 5;
});