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

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

string DoSomething(string whatever);

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

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

Любые идеи?


person Steve Dunn    schedule 15.06.2009    source источник


Ответы (3)


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

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

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

.Returns<string>(x => x);
person mhamrah    schedule 15.06.2009
comment
Кажется довольно простым, пока вам не понадобится сделать это для метода с 7 аргументами ... Когда я проверил IReturns в Moq, он определяет Returns не более чем для 4 аргументов. Есть ли простой способ обойти это? / Я имею в виду кроме изменения источника Moq / - person mizuki nakeshu; 26.06.2013
comment
хорошо, он определен для 9 аргументов в Moq v 4.0.0.0. решено :) - person mizuki nakeshu; 27.06.2013
comment
@mizukinakeshu Я бы подумал о небольшом рефакторинге метода с 9 аргументами, поскольку это звучит так, как будто класс / метод делает слишком много. Возможно, рефакторинг 9 параметров в класс или структуру настроек поможет вам позже? - person The Senator; 09.02.2015
comment
@TheSenator Согласитесь, я уже не вспоминаю, о чем идет речь, но я предполагаю, что просто взламывал несколько модульных тестов для уже существующего кода, который не должен был изменять, иначе это количество аргументов определенно требует рефакторинга. - person mizuki nakeshu; 09.02.2015
comment
Просто примечание, поскольку это меня смутило: строка в .Returns<string> относится к входным параметрам, а не к значениям, которые вы возвращаете. - person Jim; 31.07.2015
comment
Это тот же подход, который используется при имитации методов добавления и удаления в DbSet в EF6. - person IbrarMumtaz; 06.07.2017
comment
@TheSenator на предыдущей работе у нас произошел сбой сборки, потому что было изменение сигнатуры с 62 до 63 аргументов! (Это был метод поиска FWIW, но, очевидно, отчаянно нуждающийся в рефакторинге) - person stannius; 02.10.2020

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

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

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

person Steve    schedule 22.08.2012
comment
Это должен быть принятый ответ. Это именно то, что вам нужно сделать. Все остальное вызывает исключение с рядом ожидаемых аргументов. - person Chaim Eliyah; 18.02.2015
comment
Да, определенно выделяется легче для чтения и работает с ReturnsAsync тоже! - person Piotr Kula; 16.02.2017
comment
Этот ответ спас положение. Обратите внимание (будущие читатели), вы также можете пойти немного дальше. .Returns ((строка a, строка b, строка c) = ›{строка d = wow; return string.Concat (a, b, c, d);}); - person granadaCoder; 03.03.2017
comment
Лично это гораздо лучший ответ. У меня очень мало знаний о Moq, но я сразу это понял. - person unrealsoul007; 05.05.2017
comment
Для методов, возвращающих void, я использовал .Callback ((string a, Exception b, string c) = ›throw new Exception (b.Message)); - person tymtam; 12.06.2018

Универсальный метод 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);
person WDuffy    schedule 31.05.2011