2009-07-03 91 views
13

我目前正在尝试为小型图书馆建立一套或多或少的完整单元测试。由于我们希望允许不同的实现存在,我们希望这组测试是(a)通用的,以便我们可以重新使用它来测试不同的实现,并且(b)尽可能完整。对于(b)部分,我想知道是否有任何用于测试枚举类型的最佳做法。所以例如我有一个枚举如下:如何测试枚举类型?

public enum Month { 
    January, 
    February, 
    ... 
    December; 
} 

这里我想确保所有的枚举类型真的存在。这甚至是必要的吗?目前我使用Hamcrests assertThat像下面的例子:

assertThat(Month.January, is(notNullValue())); 

一个失踪“一月”枚举会导致其中一个可以通过创建缺少的枚举类型确定一个编译时错误。

我使用Java在这里,但如果你的答案是不同的语言,我不介意..

编辑:

由于mkato和马克·希思双双指出,测试可枚举没有必要,因为编译器在您使用不存在的枚举类型时不会编译。但我仍然想测试这些枚举,因为我们想构建一个独立的TCK类test.jar,它将在不同的实现上运行相同的测试。所以我的问题更像是:什么是测试枚举类型的最好方法?

想着它之后多一点,我改变了Hamcrest声明以上:

assertThat(Month.valueOf("January"), is(notNullValue())); 

这种说法现在抛出一个NPE月份的时候是不是有(还)。这种方法有什么问题吗?

回答

17

对于枚举,我只在他们实际上有方法的时候才测试它们。如果它是一个纯粹的纯数值枚举,就像你的例子,我会说不要打扰。

但是,由于您热衷于测试它,因此使用第二种方法比第一种方法好得多。第一个问题是,如果您使用IDE,则枚举上的任何重命名都会重命名测试类中的那些。

+0

我有一个枚举,有一个方法,我想测试,我是单元测试的新手,无法找出一种方法来编写该方法的测试用例,请您提供一个示例或帮助做到这一点。 – dirtydexter 2014-10-31 12:16:19

+0

如果“assertThat(Month.January,is(notNullValue()));”在OP的问题中,对于你来说还不够,我认为你最好把它当作一个单独的问题,并提供一个你想要测试的例子。听起来像你可能需要帮助JUnit本身。 – aberrant80 2014-11-03 02:42:08

3

如果您使用一切都在你的代码的几个月,你的IDE不会让你编译,所以我觉得你不需要单元测试。

但是,如果你使用的是他们与反思,即使你删除一个月内,它将编译,所以它是有效的把一个单元测试。

+0

单元测试不知道你的月份将如何使用,甚至不知道它们将来如何使用。这意味着您应该为它们包含单元测试,即使应用程序在所有月份不存在的情况下都不会编译。注意事项:确保你的复杂对象被单元测试覆盖,然后担心简单的问题(比如没有方法的枚举)。 – 2017-05-07 09:00:07

4

通常我会说这是矫枉过正,但偶尔会有编写枚举单元测试的原因。

有时分配给枚举成员的值必须永远不会改变或传统的装载持久数据将失败。同样,显然未使用的成员不能被删除。单元测试可以用来防止开发人员进行更改而不会意识到这些影响。

8

我同意aberrant80

对于枚举,我只在他们实际上有方法时才测试它们。 如果这是一个纯粹的纯数值枚举像你的例子,我会说不要 麻烦。

但是,由于您热衷于测试它,因此使用第二个选项 要比第一个选项好得多。第一个问题是,如果您使用IDE, 中的任何重命名都会重命名您的测试类中的 。

我将通过添加单元测试来扩展Enum可能非常有用。如果您在大型代码库中工作,则编译时间开始增加,单元测试可以成为验证功能的更快方式(测试只构建它们的依赖关系)。另一个非常大的优势是其他开发人员无法无意地更改代码的功能(对于非常大的团队来说是一个巨大的问题)。

对于所有的测试驱动开发,围绕Enums方法的测试减少了代码库中的错误数量。

简单的例子

public enum Multiplier { 
    DOUBLE(2.0), 
    TRIPLE(3.0); 

    private final double multiplier; 

    Multiplier(double multiplier) { 
     this.multiplier = multiplier; 
    } 

    Double applyMultiplier(Double value) { 
     return multiplier * value; 
    } 

} 

public class MultiplierTest { 

    @Test 
    public void should() { 
     assertThat(Multiplier.DOUBLE.applyMultiplier(1.0), is(2.0)); 
     assertThat(Multiplier.TRIPLE.applyMultiplier(1.0), is(3.0)); 
    } 
} 
2

你可以测试是否有确切一些价值观,通过例如:

for(MyBoolean b : MyBoolean.values()) { 
    switch(b) { 
    case TRUE: 
     break; 
    case FALSE: 
     break; 
    default: 
     throw new IllegalArgumentException(b.toString()); 
} 

for(String s : new String[]{"TRUE", "FALSE" }) { 
    MyBoolean.valueOf(s); 
} 

如果有人删除或添加值,一些测试的失败。