Представьте себе этот класс
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler в тесте Foo, как я смогу проверить, что Bar()
было передано _h.AsyncHandle
?
Ответы:
Вы можете использовать метод Mock.Callback:
Если вы хотите проверить только что-то простое в переданном аргументе, вы также можете сделать это напрямую:
источник
Callback<>()
методе Moq. Например, если у вашего метода есть определениеHandler.AnsyncHandle(string, SomeResponse)
, вам нужно/* ... */.Callback<string, SomeResponse>(r => result = r);
. Я не нашел этого явно заявленного во многих местах, поэтому я решил добавить это сюда./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
помощник?Ответ Гэмлора сработал для меня, но я подумал, что расширю комментарий Джона Карпентера, потому что я искал решение, включающее более одного параметра. Я полагал, что другие люди, которые натыкаются на эту страницу, могут быть в подобной ситуации. Я нашел эту информацию в документации Moq .
Я буду использовать пример Gamlor, но давайте представим, что метод AsyncHandle принимает два аргумента: a
string
иSomeResponse
объект.По сути, вам просто нужно добавить еще один
It.IsAny<>()
с соответствующим типом, добавить еще один тип вCallback
метод и изменить лямбда-выражение в зависимости от ситуации.источник
Метод Callback, безусловно, будет работать, но если вы делаете это для метода с большим количеством параметров, он может быть немного многословным. Вот кое-что, что я использовал, чтобы удалить часть шаблона.
Вот источник для ArgumentCaptor:
источник
Ответ Гамлора работает, но другой способ сделать это (и тот, который я считаю более выразительным в тесте) - это ...
Проверка очень мощная, и стоит потратить время, чтобы привыкнуть.
источник
Альтернативой также является использование
Capture.In
функцииmoq
. Этоmoq
функция OOTB, которая позволяет захватывать аргументы в коллекции.источник
Callback
ИМО. Поскольку вы используете Capture непосредственно в списке параметров, он гораздо менее подвержен проблемам при рефакторинге списка параметров метода и, следовательно, делает тесты менее хрупкими. С Callback вы должны поддерживать параметры, передаваемые в программе установки, в синхронизации с параметрами типа, используемыми для Callback, и это определенно вызывало у меня проблемы в прошлом.Вы могли бы использовать
It.Is<TValue>()
matcher.источник
Это также работает:
источник
Здесь много хороших ответов! Идите с готовым набором функций Moq, пока вам не понадобится сделать утверждения о нескольких параметрах класса, передаваемых вашим зависимостям. Однако, если вы окажетесь в такой ситуации, функция Moq Verify с It.Is matchers не поможет изолировать неудачу теста, а способ захвата аргументов Returns / Callback добавляет ненужные строки кода в ваш тест (и долгие тесты мне не нужны).
Вот суть: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b с расширением Moq (4.12), которое я написал и которое дает более декларативный способ делать утверждения об аргументах, передаваемых имитам, без вышеупомянутых недостатков. Вот как выглядит раздел Verify:
Я был бы рад, если бы Moq предоставил функцию, которая выполняет то же самое, будучи в то же время декларативной и обеспечивая изоляцию ошибок, что делает это. Скрещенные пальцы!
источник