程序演示TDD + Mocking

时间:2012-03-11 17:29:25

标签: mocking tdd easymock

我必须编写一个程序,它接受一个I​​nteger并将其转换为英文单词版本。

例如:

Input:  21
Output: twenty one
Input:  110 
Output: one hundred and ten

我需要程序来演示TDD,所以我想使用模拟。

我编写了一个具有转换功能的类(基于2个英语单词数组)。我现在需要以这样的方式设计程序,我可以使用Easymock进行演示。

因此,我需要创建一个接口作为我的模拟主题。谁能给我任何关于如何设计我的程序的指示?

这会合适吗?

  1. 编写一个Converter类,该类具有对名为ConverterInterface的接口的引用。然后我可以模拟界面并将其设置为我的Converter类。
  2. 欢迎任何帮助。

3 个答案:

答案 0 :(得分:1)

您可以在不进行嘲笑的情况下演示TDD。事实上,嘲弄可能会使TDD新手感到困惑。我只是从测试驱动你想要开发的功能开始,然后担心以后嘲笑。让我们假设您已经测试了数字转换为英文转换器(根据您的描述它似乎没有完成),并且您有一个看起来像这样的类:

public class NumberConverterTest { ... }

public class NumberConverter {
  public String toEnglish(int number) { ... }
}

您可能也有某种主要类:

public class NumberConverterMain {
  public void main(String[] args) {
    NumberConverter converter = new NumberConverter();
    System.out.println(converter.toEnglish(args[0]);
  }
}

你现在已经展示了TDD而没有嘲笑。在尝试练习TDD时,总是会提出嘲弄问题。为了演示模拟,您可以围绕toEnglish方法添加一些任意业务规则,例如“所有对大于1000的数字的请求必须记录到大数字部门”。知道大量部门托管在另一台我们不想依赖的服务器上,我们可以测试驱动界面并模拟它。

public class NumberConverterTest {
  // ..
  @Test public void theLargeNumberDepartmentIsNotifiedForLargeNumbers() {
     LargeNumberDepartment department = new MockLargeNumberDepartment(1000);
     NumberConverter converter = new NumberConverter(department);
     converter.toEnglish(1000);
     assertTrue(department.wasNotifiedWith(1000));
  }

  public static MockLargeNumberDepartment implements LargeNumberDepartment {

     private int valueRequested;

     public void MockLargeNumberDepartment(int threshhold) {
       this.threshold = threshold;
     }

     public int notificationThreshold() {
       return this.threshold;
     }

     public void largeNumberReceived(int value) {
       valueRequested = value;
     }

     public boolean wasNotifiedWith(int value) {
       assertEquals(value, valueRequested);
       return true;
     }
  }
}

// In NumberConverter.java
public class NumberConverter {
  public NumberConverter(LargeNumberDepartment department) {
    this.department = department;
  }

  public String toEnglish(int value) {
    if(value > department.notificationThreshold())
      department.largeNumberReceived(value);
    return convertIt(value);  
  }
}

答案 1 :(得分:0)

首先,我同意@Don Roby的观点,最好的办法是先实际编写测试,看看有什么东西可以作为嘲笑的东西。

我看到这个程序有不同的元素。

  1. 'main'可执行部分
  2. 处理命令行参数的逻辑
  3. 将数字转换为单词的算法
  4. 显示输出的机制
  5. 前两个可能很简单。第三个可能很复杂,有自己的类。第四个可能很简单,打印到控制台,但如果这是一个真正的程序,抽象的地方可能有一些价值,所以你可以插入其他方法,如写入文件或数据库或其他什么,所以在那里设置一个具有单独运行的具体实现的接口并不是完全可取的。

答案 2 :(得分:0)

只有在组件之间有一些责任划分时,模拟通常才有用,其中关注点的分离是通过接口“实现”的。您所说的问题似乎太狭隘,无法说明这一点。一个可行的想法是扩展您的问题,并将数字转换器设计为多种语言。在这种情况下,我希望出现一个策略模式,INumberTranslator接口公开一个字符串Translate(int number)方法。

通过首先编写“翻译为英语”要求的测试,然后将要求更改为“我们也需要用西班牙语支持这个”,你可以相当顺利地从没有模拟的TDD移动到带有模拟的TDD。