Как BDD с GWT с помощью MSpec? Правильный способ написать этот сценарий

Я только начинаю практиковать BDD, используя подход GWT к следующему коду, и только что понял, что не могу выполнить второй тест.

Мой GWT выглядит примерно так

Given there exists an open query
When the user replies to the query
Then it should save the reply if the reply is not blank

Затем он должен уведомить пользователя и не сохранять ответ, если он пуст.

Так что я закодировал это так

public class when_user_replies_to_the_query : OpenQuery
{
    Because
    {
         query.Reply(data);
    }

    ThenIt should_save_the_reply_to_the_database_if_there_is_a_reply

    ThenIt should_notify_the_user_if_there_is_no_text_in_the_reply_and_not_save_to_database
}

public class Query
{
    void Reply(string data)
    {
        //do something
    }
}

Но потом я понял, что не могу сделать второй случай, потому что в первом случае данные должны содержать что-то, а во втором случае данные должны быть пустой строкой.

Означает ли это, что я должен разделить свой GWT на что-то вроде

Given the reply is blank
When the user replies to the query
Then it should notify the user ......

Если это так, то я бы написал огромное количество сценариев нулевого случая для возврата

values being null. Such as
Given the database is null
When retrieving queries
Should reply with error message
When saving queries
Should save to file and reply with error message
When // basically doing anything
Should //give appropriate response

Это то, как я должен писать свои спецификации BDD? И я вообще в том форуме О_О?


person Joe    schedule 22.01.2010    source источник


Ответы (1)


Вы хотели бы инвертировать два предложения Then, потому что они в основном формируют разные контексты, в которых используется класс Query. Когда вы читаете оба утверждения Then, вы можете видеть, что «если не пусто» и «пусто» формируют оба контекста.

  1. Контекст № 1:

    Given an open query
    Given a non-blank reply
    When the user replies to the query
    It should save the reply
    
    public class When_the_user_replies_to_the_query_and_the_reply_is_not_blank
    {
       static Query Query;
    
       Establish context = () =>
       {
           Query = new Query();
       };
    
       Because of = () =>
       {
           Query.Reply("answer");
       };
    
       It should_save_the_reply = () =>
       {
           // Use your imagination
       };
    }
    
  2. Контекст № 2:

    Given an open query
    Given a blank reply
    When the user replies to the query
    It should not save the reply
    It should notify the user
    
    public class When_the_user_replies_to_the_query_and_the_reply_is_blank
    {
       static Query Query;
    
       Establish context = () =>
       {
           Query = new Query();
       };
    
       Because of = () =>
       {
           Query.Reply(String.Empty);
       };
    
       It should_not_save_the_reply = () =>
       {
           // Use your imagination
       };
    
       It should_notify_the_user = () =>
       {
           // Use your imagination
       };
    }
    

Учитывая, что у вас может быть несколько возможных значений «пустого ответа» (null, String.Empty, " ", \r\n), вы можете написать контексты для любого из них. Я часто не пишу спецификации для любых мыслимых комбинаций значений, а скорее

  • иметь один контекст для "счастливого пути", т.е. ответ не пустой
  • иметь один контекст для пустых ответов

В свете вашего примера можно утверждать, что класс Query не является подходящим местом для принятия решения о том, удовлетворяет ли ответ спецификации «не пуст». Вы должны скорее закодировать это решение в отдельном классе, и Query должен полагаться на решение этого. Это принесет некоторые преимущества:

  • Разделение ответственности: класс Query и спецификация могут развиваться отдельно
  • Вы можете повторно использовать спецификацию в нескольких местах, намекая на проблему с ответом до того, как пользователь опубликует свой пустой ответ.
  • Вы можете получить тестируемую спецификацию отдельно, не беспокоясь об уведомлениях пользователей и сохранении базы данных, тем самым предотвращая взрыв контекста для Query проблем.
person Alexander Groß    schedule 22.01.2010