2013-10-04 2 views
1

Я ищу кое-какие разъяснения относительно Arrange/Act/Assert, которые я реализую в своем процессе разработки как Given-When-Then. Я пытаюсь придерживаться концепции, но я обнаружил, что во время определенных событий (в частности, для ввода пользователем) мне нужно пересмотреть действие «Действие» как действие «Упорядочить», чтобы оно было правильно захвачено в модульном тесте , Я использую Moq как мой издевательский каркас здесь.Дано-когда-Тогда при работе с пользовательским вводом

Например: В моем проекте фокальной точкой кода является изображение, предоставленное пользователем. Существует функция, в которой пользователь может выбрать изображение, но если изображение уже присутствует, оно будет запрашивать пользователя, если оно хочет заменить активное изображение, или отменить действие и сохранить активное изображение. Я чувствую, что правильный способ написания этого конкретного сценария будет:

Учитывая рабочее пространство с изображением уже присутствует
Когда пользователь запрашивает новый образ
И пользователь выбирает заменить активный образ
Затем программа должна заменить изображение

Testwise, это выглядит что-нибудь г, как это:

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 происходит после того, как называется View-х Raise. Таким образом, мне нужно переместить Setup до того, как (и с помощью Setup делает его чувствовать, как настроить «Упорядочить» в любом случае):

Учитывая рабочее пространство с изображением уже присутствует
И пользователь выбирает заменить активный образ
Когда пользователь запрашивает новый образ
Тогда программа должна заменить изображение

Но теперь мой сценарий выглядит не по порядку и что он не течет правильно. Я чувствую, что выбор пользователя для замены изображения (Setup), так как это происходит после выбор пользователя для добавления нового изображения (Raise) должен быть частью шага «Акт», но для того, чтобы он правильно высмеивал , Мне нужно поставить его на шаг Arrange.

Я использую здесь насмешливую структуру? Есть лучший способ сделать это? Или я нерешительно беспокоюсь о том, где шаг ввода пользователя должен быть расположен в настройке «Дано-когда-Тогда»?

Заранее спасибо.

+0

С помощью некоторых пользовательских методов расширения вы можете соединять свои «Когда-И», поэтому вы пишете их, когда они поступают логически, но вместо прямого вызова Moq поместите лямбда в стек и выполните их в обратном порядке после завершения выражения. –

ответ

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(); 
} 

Это делает на самом деле тест чтения лучше (то есть теперь он самодокументируется), и это позволит повторно использовать шаги, если это необходимо.

+0

Ну, это довольно простое, прямолинейное решение «почему-не-я-думаю-из-того». Спасибо. Выбор слов имеет значение! И для записи - я уже делаю то, что вы делаете (размещая действия в методах), я просто хотел, чтобы это было просто для моего вопроса. Я изначально пытался использовать SpecFlow для BDD, но он не течет со мной, поэтому я решил просто обрабатывать все методы вручную, как это, и я считаю, что он работает хорошо. Еще раз спасибо! – Arclight

+0

@Arclight рад, что я мог бы помочь :) –

Смежные вопросы