Given-When-Then при работе с пользовательским вводом
Я ищу некоторые разъяснения относительно Arrange/Act/Assert, которые я реализую в процессе разработки как "Given-When-Then". Я пытаюсь придерживаться этой концепции, но обнаруживаю, что во время определенных событий (в частности, пользовательского ввода) мне приходится пересматривать действие "Act" как действие "Arrange", чтобы оно было правильно зафиксировано в модульном тесте., Я использую Moq в качестве моей насмешливой основы здесь.
Например: в моем проекте фокусом кода является изображение, предоставленное пользователем. Функция существует, когда пользователь может выбрать изображение, но если изображение уже присутствует, он запросит пользователя, хотят ли они заменить активное изображение, или отменит действие и сохранит активное изображение. Я чувствую, что правильным способом написания этого конкретного сценария будет:
Учитывая рабочее пространство с изображением уже присутствует
Когда пользователь запрашивает новое изображение
И пользователь выбирает заменить активное изображение
Тогда программа должна заменить изображение
В тестовом режиме это выглядит примерно так:
mockModel.SetupProperty(m => m.Image, new Bitmap(100, 100)); // Given
mockView.Raise(v => v.UserRequestsNewImage += null); // When
mockMBox.Setup(mb => mb.ViewResult).Returns(ViewResult.OK); // And
mockView.Verify(v => v.OpenAddImageFileDialog(), Times.Once); // Then
Codewise, в моем докладчике, выглядит примерно так:
private void view_UserRequestsNewImage()
{
if (model.Image != null)
{
mbox.ShowDialog();
if (mbox.ViewResult == ViewResult.Cancel)
return;
}
view.OpenAddImageFileDialog();
}
Но это не удается, потому что окно сообщений Setup
происходит после просмотра Raise
называется. Как таковой, мне нужно переместить Setup
перед этим (и используя Setup
в любом случае это похоже на "Arrange"):
Учитывая рабочее пространство с изображением уже присутствует
И пользователь выбирает заменить активное изображение
Когда пользователь запрашивает новое изображение
Тогда программа должна заменить изображение
Но теперь, мой сценарий чувствует себя не в порядке, и что он не работает правильно. Я чувствую, что выбор пользователя заменить изображение (Setup
), поскольку это происходит после выбора пользователем добавления нового изображения (Raise
), должен быть частью шага Act, но для того, чтобы он правильно издевался, мне нужно поместить его в шаг Arrange.
Я неправильно использую фреймворк? Есть лучший способ сделать это? Или я нереально беспокоюсь о том, где должен находиться шаг пользовательского ввода в настройке "Предоставлено, когда"?
Заранее спасибо.
1 ответ
"Когда пользователь запрашивает новое изображение", этот пользователь должен выбрать заменить текущее изображение.
Таким образом, вы можете переписать "Дано, когда, потом", чтобы прочитать:
- Учитывая рабочее пространство с изображением уже присутствует
- Когда пользователь выбирает заменить активное изображение
- Тогда программа должна заменить изображение
то есть опускаем "Когда", в котором говорится, что "пользователь запрашивает новое изображение", так как они должны это делать в любом случае при замене текущего изображения.
Также я угробил бы комментарии (запах кода, хотя их и не так много!) И поместил эти шаги теста в небольшие методы, например:
void GivenImageAlreadyPresent()
{
mockModel.SetupProperty(m => m.Image, new Bitmap(100, 100));
}
void WhenActiveImageReplaced()
{
mockMBox.Setup(mb => mb.ViewResult).Returns(ViewResult.OK);
mockView.Raise(v => v.UserRequestsNewImage += null);
}
void ThenImageShouldBeReplaced()
{
mockView.Verify(v => v.OpenAddImageFileDialog(), Times.Once);
}
void Test()
{
GivenImageAlreadyPresent();
WhenActiveImageReplaced();
ThenImageShouldBeReplaced();
}
Это делает фактически тестовое чтение лучше (т.е. теперь оно самодокументируется), и это позволит повторно использовать шаги, если это будет необходимо.