2012-03-11 67 views
0

我必须编写一个程序,该程序需要一个整数并将其转换为其英文单词版本。程序演示TDD +嘲讽

例如:

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

我需要的程序来演示TDD,所以我想用嘲讽。

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

因此,我需要创建一个接口作为我的模拟主题。任何人都可以给我任何指导我如何设计我的程序?

这会适合吗?

  1. 编写一个Converter类,该类引用了名为ConverterInterface的接口。然后,我可以模拟界面并将其设置为我的Converter类。

任何帮助,欢迎。

+0

嘲笑通常用于模拟别的东西。你想要模拟什么?输出机制? – 2012-03-11 17:34:14

+0

如果你想演示TDD,你应该丢掉你的代码并开始编写测试。 – 2012-03-11 17:45:58

+0

@vaughan:这是我的问题。我的程序可以很容易地编写而不用嘲笑,但是我需要用一种方式来写作,以演示嘲笑。因此,我需要这样设计它。设计显然会令人费解,但这个练习是为了展示嘲笑。 – TheCoder 2012-03-11 17:57:52

回答

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); 
    } 
} 
+0

谢谢所有回答。我现在已经在你的帮助下编写了这个程序。 – TheCoder 2012-03-12 21:36:42

0

首先,我同意@Don Roby所说的最好的做法是首先实际编写测试,然后看看哪些东西会成为模拟某些东西的机会。

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

  1. 的“主”可执行部分
  2. 用于处理所述命令行参数
  3. 该算法对于数字转换为字
  4. 用于显示输出

第一机制中的逻辑两个可能非常简单。第三个可能足够复杂以拥有自己的班级。第四种方法对于打印到控制台可能非常简单,但如果这是某种真正的程序,那么在抽象它发送答案的位置时可能会有一些价值,因此您可以插入其他方法,如写入文件或数据库或其他任何东西,所以它不是完全有人设计一个具有独立运行的具体实现的接口。

+0

所以你说我应该写一个名为'Converter'的接口,它有一个名为'display'的抽象方法。然后模拟这个接口,并在单元测试中传递System.out?那么在真正的程序中,显示器可以显示在网页上? – TheCoder 2012-03-11 20:19:46

+0

我已经将我的程序分成如下:转换器类与主要方法。 UserInput类+接口以从用户获得输入。算法类+接口做转换。仍然没有找到一个理由来嘲笑一些东西... – TheCoder 2012-03-11 23:47:43

+0

好吧,如果你正在测试你的主要方法,你不测试你的算法类和你的UserInput类,你只要确保它们被调用,如你所期望的与模拟),然后为算法编写单独的单元测试,并为UserInput分别进行单元测试。这样,如果你有很多可能与UserInput出错的地方(不好的格式,坏的管道,不管),你可以单独测试所有那些路径,而不是算法逻辑,它有一组完全不同的东西,可能会出错。 – jhericks 2012-03-12 05:27:46

0

只有当组件之间有责任分离时,通过接口“关注”分离才能实现模拟。你所说的问题似乎太窄而无法说明这一点。一个可行的想法是扩展你的问题,并设计一个号码翻译到多种语言。在这种情况下,我期望一个策略模式出现,一个INumberTranslator接口暴露一个字符串Translate(int number)方法。

通过首先为“translate to English”需求编写测试,然后将需求更改为“我们需要用西班牙语支持这个”,您可以从TDD非常顺利地从移动到TDD的移动。