c# wpf unit-testing moq ivalueconverter

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; });