如何使用MSpec使用GWT进行BDD?编写此方案的正确方法

时间:2010-01-22 06:18:52

标签: unit-testing moq bdd mspec

我刚刚开始使用GWT方法练习BDD以下代码,并且意识到我无法进行第二次测试。

我的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规范吗?我甚至在正确的论坛O_O?

1 个答案:

答案 0 :(得分:2)

您可能希望反转两个Then子句,因为它们基本上形成了运行Query类的不同上下文。当您阅读两个Then个州时,您可以看到两个上下文中的“if not not blank”和“is blank”。

  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
       };
    }
    
  3. 考虑到您可以有多个可能的“空回复”值(nullString.Empty" "\r\n),您可以为其中任何一个编写上下文。我经常不为任何可以想象的值组合编写规范,而是

    • 有一个“快乐路径”的上下文,即回复不为空
    • 有一个空回复的上下文

    根据您的示例,可以认为Query类不是确定答复是否满足“非空”规范的正确位置。您应该在单独的类中编写该决策,Query应该依赖于该决策。这会带来一些好处:

    • 关注点分离:Query类和规范可以单独发展
    • 您可以在多个地方重复使用该规范,在用户发布空回复之前提示回复问题
    • 您可以单独获取待测规范,而无需担心用户通知和数据库保存,从而防止Query关注点的上下文爆炸