wake-up-neo.com

Moq + Unit Testing - System.Reflection.TargetParameterCountException: Nicht übereinstimmende Parameteranzahl

Ich versuche, ein Lambda mit einer Funktion für mehrere Parameter zu verwenden, aber Moq löst diese Ausnahme zur Laufzeit aus, wenn ich versuche, die Zeile mock.Object.Convert(value, null, null, null); aufzurufen.

System.Reflection.TargetParameterCountException: Nicht übereinstimmende Parameteranzahl

Der Code lautet:

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

Was ist der richtige Weg, um es zu implementieren?

67
m-y

Es ist Ihre Returns -Klausel. Sie haben eine 4-Parameter-Methode, die Sie einrichten, aber Sie verwenden nur ein 1-Parameter-Lambda. Ich habe Folgendes ohne Probleme ausgeführt:

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

Keine Ausnahmen, Test bestanden.

127
Erik Dietrich

Keine Antwort für OP, aber vielleicht für zukünftige Googler:

Ich hatte ein Callback, das nicht mit der Signatur der einzurichtenden Methode übereinstimmte

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

Dies war das Ergebnis einiger Umgestaltungen und das Umgestaltungswerkzeug konnte natürlich nicht erkennen, dass die Signatur Callback falsch war

5
fiat

In meinem Fall dachte ich, dass der Typ in Returns<> Der Ausgabetyp ist, aber tatsächlich der/die Eingabetyp (en).

Also, wenn Sie eine Methode haben

public virtual string Foo(int a, int b) { ... }

Die korrekte Klausel ist .Returns<int, int>(...), NOT .Returns<string>(...), was ich anfangs gedacht habe.

Mein Fehler war, dass ich eine Funktion mit dem gleichen Eingabe- und Rückgabetyp getestet habe - zum Beispiel public virtual string Foo(string a).

1
sashoalm

Vielleicht liegt es daran, dass Sie null übergeben, aber It.IsAny<Object>() erwartet object mit Ausnahme von null? Was passiert, wenn Sie Folgendes tun:

var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);

Dies ist nur ein Stich in die Dunkelheit von mir, ich kenne Rhino.Mocks besser.


Meine 2. Vermutung:

Nachdem Sie sich das Moq.chm angesehen haben, das mit dem Download geliefert wird,

Sie verwenden die Setup(Expression<Action<T>>) -Methode, die "ein Setup für den verspotteten Typ für einen Aufruf einer void -Methode angibt."

Sie möchten die Methode Setup<TResult>(Expression<Func<T,TResult>>), die "ein Setup für den verspotteten Typ für einen Aufruf einer Wertrückgabemethode angibt".

Sie könnten also versuchen:

mock.Setup<Int32>(
    conv => {
        conv.Convert(
            It.IsAny<Object>(), 
            It.IsAny<Type>(),
            It.IsAny<Object>(), 
            It.IsAny<CultureInfo>());
        return  num + 5;
        });
1
Grokodile