#c# #unit-testing #action #moq #invoke
#c# #модульное тестирование #Экшен #moq #вызвать
Вопрос:
В принципе, у меня есть метод в моем классе, который вызывает Action<T>
, если выполняются определенные условия. Как я могу выполнить модульное тестирование, чтобы убедиться, что действие вызвано?
public class MyClass<T>
{
private IDBService _dbService;
private Action<T> _action;
public MyClass(IDBService dbService, Action<T> action)
{
if (dbService == null) throw new ArgumentNullException("dbService");
if (action == null) throw new ArgumentNullException("action");
_dbService = dbService;
_action = action;
}
public void CallActionIfPossible(T param)
{
if (_dbService.IsTopUser)
action(param);
}
}
Комментарии:
1. Покажите нам свой текущий код, чтобы мы могли создать ответ?
Ответ №1:
Ну, основная идея заключается в том, что где-то Action<T>
происходит какое-то изменение состояния (если этого не происходит, какой смысл?). Итак, модульный тест показывает, что ожидаемое изменение состояния происходит при выполнении условий, и что ожидаемое изменение состояния не происходит, когда условия не выполняются.
Конечно, в идеале вы издеваетесь над Action<T>
тем, чтобы тестирование состояния было очень простым. Для этого вам не нужен Moq или любой другой фреймворк-макет:
bool actionWasInvoked = false;
Action<Foo> action = foo => actionWasInvoked = true;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is invoked
bar.M(action);
Assert.IsTrue(actionWasInvoked);
и
bool actionWasInvoked = false;
Action<Foo> action = foo => actionWasInvoked = true;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is NOT invoked
bar.M(action);
Assert.IsFalse(actionWasInvoked);
Конечно, я не знаю вашей точной настройки. Может быть, вы переходите к action
построению Bar
, или, может быть, у вас есть какой-то другой способ настройки действия. Но идея должна быть ясна.
Ответ №2:
Ответ Джейсона хорош, но одно предостережение, которое часто упускается из виду, заключается в том, что вам часто нужно будет проверять определенное количество вызовов (например, оно не только было вызвано, но и было вызвано ровно один раз). Поэтому я часто делаю что-то вроде этого:
var callCount = 0;
Action<Foo> action = _ => callCount ;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is invoked
bar.M(action);
Assert.That(callCount, Is.EqualTo(1));
Комментарии:
1. 1 Мне нравится идея, стоящая за этим (убедитесь, что у него есть необходимое количество вызовов).