#c# #wpf #unit-testing #moq #ivalueconverter
#c# #wpf #модульное тестирование #moq #ivalueconverter
Вопрос:
Я пытаюсь использовать лямбда-выражение с функцией с несколькими параметрами, но Moq выдает это исключение во время выполнения, когда я пытаюсь вызвать mock.Object.Convert(value, null, null, null);
строку.
Система.Отражение.TargetParameterCountException: несоответствие количества параметров
Код:
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);
Каков правильный способ его реализации?
Ответ №1:
Это ваше Returns
предложение. У вас есть метод с 4 параметрами, который вы настраиваете, но вы используете только 1 параметр lambda. Я без проблем выполнил следующее:
[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);
}
Никаких исключений, тест пройден.
Комментарии:
1. Я собирался спросить, было ли это проверкой фреймворка или нет, но я решил, что сомневаюсь, что, возможно, это был промежуточный код, чтобы попытаться заставить макет вести себя должным образом.
2. Я предполагаю, что это тоже так, но это все равно заставило меня усмехнуться.
3. Я слышу тебя. Когда я выполнил код, я подумал: «Ага, библиотеки фреймворка все еще работают». 🙂
Ответ №2:
Не ответ для OP, но, возможно, для будущих пользователей Google:
У меня был Callback
, который не соответствовал сигнатуре настраиваемого метода
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.
});
Это было результатом некоторого рефакторинга, и инструмент рефакторинга, конечно, не мог понять, что Callback
подпись была неверной
Комментарии:
1. вау, я бился головой об эту же проблему и продолжал замалчивать обратный вызов, пока не прочитал ваш пост. Очень полезно, и я рад, что вы опубликовали его.
2. Это тоже была моя проблема. Я добавил параметр в метод, исправил вызов Setup(), но пропустил параметр обратного вызова () .
Ответ №3:
Возможно, это потому, что вы проходите null
, но It.IsAny<Object>()
ожидаете каких-либо object
исключений null
? Что произойдет, если вы выполните следующие действия?:
var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);
Это просто удар в темноте от меня, я больше знаком с Rhino.Издевается.
Мое 2-е предположение:
Посмотрев на Moq.chm, который поставляется с загрузкой,
Вы используете Setup(Expression<Action<T>>)
метод, который «Задает настройку для издевательского типа для вызова void
метода».
Вам нужен Setup<TResult>(Expression<Func<T,TResult>>)
метод, который «Задает настройку для издевательского типа для вызова метода, возвращающего значение».
Итак, вы могли бы попробовать:
mock.Setup<Int32>(
conv => {
conv.Convert(
It.IsAny<Object>(),
It.IsAny<Type>(),
It.IsAny<Object>(),
It.IsAny<CultureInfo>());
return num 5;
});
Комментарии:
1. макет. Setup<TResult> выводит возвращаемый тип как Object, поскольку метод Convert возвращает объект.
Ответ №4:
В моем случае я думал, что вводимый тип Returns<>
является типом вывода, но на самом деле это были типы ввода.
Итак, если у вас есть метод
public virtual string Foo(int a, int b) { ... }
Правильное предложение .Returns<int, int>(...)
, А не .Returns<string>(...)
то, что я думал изначально.
Моя ошибка заключалась в том, что я изначально тестировал функцию с тем же типом ввода и возвращаемого значения — например public virtual string Foo(string a)
.