Возвращаемое значение, которое было передано в метод

391

У меня есть метод на интерфейсе:

string DoSomething(string whatever);

Я хочу поиграть с MOQ, чтобы он возвращал все, что было передано - что-то вроде:

_mock.Setup( theObject => theObject.DoSomething( It.IsAny<string>( ) ) )
   .Returns( [the parameter that was passed] ) ;

Любые идеи?

Стив Данн
источник

Ответы:

527

Вы можете использовать лямбду с входным параметром, например так:

.Returns((string myval) => { return myval; });

Или чуть более читабельно:

.Returns<string>(x => x);
mhamrah
источник
1
Кажется , довольно легко , пока вы не должны делать это для метода с 7 аргументов ... Когда я осмотрел IReturnsв Moq, он определяет Returnsдля 4 аргументов в большинстве . Есть ли простой способ обойти это? / Я имею в виду, за исключением изменения источника Moq /
mizuki nakeshu
14
хорошо, это определено для 9 аргументов в Moqv 4.0.0.0. решено :)
mizuki nakeshu
14
@mizukinakeshu Я бы посоветовал немного изменить метод 9 аргументов, поскольку кажется, что класс / метод делает слишком много. Возможно, рефакторинг 9 параметров в класс настроек или структуру, чтобы помочь вам позже?
Сенатор
@TheSenator Согласитесь, я еще не вспомнил, о чем идет речь, но, полагаю, я просто взламывал некоторые модульные тесты вместе для уже существующего кода, который я не должен был изменять, в противном случае это количество аргументов определенно требует рефакторинга.
Мизуки Накешу
27
Просто заметьте, как это смутило меня: строка .Returns<string>относится к входным параметрам, а не к возвращаемым значениям.
Джим
241

Еще более полезно, если у вас есть несколько параметров, вы можете получить доступ к любому / всем из них с помощью:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>())
     .Returns((string a, string b, string c) => string.Concat(a,b,c));

Вам всегда нужно ссылаться на все аргументы, чтобы соответствовать сигнатуре метода, даже если вы собираетесь использовать только один из них.

Стив
источник
17
Это должен быть принятый ответ. Это именно то, что вам нужно сделать. Все остальное выдает исключение «количество ожидаемых аргументов».
Хаим Элия
Да, определенно легче читать и работать с ним ReturnsAsyncтоже!
Петр Кула
1
Этот ответ спас день. Обратите внимание (будущие читатели), вы можете сделать это еще дальше. .Returns ((строка a, строка b, строка c) => {строка d = "wow"; вернуть строку .Concat (a, b, c, d);});
granadaCoder
1
Лично это гораздо лучший ответ. Я очень мало знаю о Moq, но все же сразу понял.
unrealsoul007
Для методов, возвращающих void, я использовал .Callback ((строка a, Exception b, строка c) => throw new Exception (b.Message));
тымтам
62

Универсальный Returns<T>метод может хорошо справиться с этой ситуацией.

_mock.Setup(x => x.DoSomething(It.IsAny<string>())).Returns<string>(x => x);

Или, если метод требует нескольких входов, укажите их так:

_mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<int>())).Returns((string x, int y) => x);
WDuffy
источник