Учитывая следующий интерфейс:
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Попытка издеваться над ним с помощью Moq:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
дает следующую ошибку во время компиляции:
Дерево выражения не может содержать вызов или вызов, использующий необязательные аргументы.
Я обнаружил, что проблема выше поднята как улучшение в списке проблем Moq, и похоже, что она относится к выпуску 4.5 (когда бы то ни было).
Мой вопрос: что мне делать, учитывая, что вышеуказанное не будет исправлено в ближайшее время? Есть ли у меня варианты только либо явно устанавливать значение по умолчанию для необязательного параметра каждый раз, когда я издеваться над ним (какой вид побеждает точку указания его в первую очередь), либо создавать перегрузку без bool (например, что я сделал бы до C # 4)?
Или кто-нибудь встречал более умный способ побороть эту проблему?
источник
Ответы:
Я считаю, что сейчас ваш единственный выбор - явно включить
bool
параметр в настройку дляFoo
.Я не думаю, что это противоречит цели указания значения по умолчанию. Значение по умолчанию - это удобство для вызова кода, но я думаю, что вы должны быть явными в своих тестах. Скажем, вы можете не указывать
bool
параметр. Что произойдет, если в будущем кто-то изменит значение по умолчаниюb
наtrue
? Это приведет к непройденным тестам (и это справедливо), но они будут более трудно исправить из - за скрытое предположение , чтоb
естьfalse
. Явное указаниеbool
параметра имеет еще одно преимущество: оно улучшает читаемость ваших тестов. Кто-то, просматривая их, быстро поймет, что есть однаFoo
функция, которая принимает два параметра. По крайней мере, это мои 2 цента :)Что касается указания его каждый раз, когда вы имитируете его, не дублируйте код: создайте и / или инициализируйте макет в функции, чтобы у вас была только одна точка изменения. Если вы действительно хотите, вы можете преодолеть очевидный недостаток Moq, скопировав
Foo
параметры в эту функцию инициализации:источник
if (!x) {} else {}
Только что столкнулся с этой проблемой сегодня, Moq не поддерживает этот вариант использования. Таким образом, кажется, что переопределения метода было бы достаточно в этом случае.
Теперь доступны оба метода, и этот пример будет работать:
источник
Используя Moq версии 4.10.1, я смог сделать следующее
С интерфейсом:
И издеваться
Разрешает вызов Foo с первым параметром, хорошо
источник