【发布时间】:2015-05-16 01:39:38
【问题描述】:
我有一个 switch 语句来处理 java enum foo,并且正在使用 spock 编写一些常规单元测试。我已经添加了一个测试,它验证当前处理了每种类型的 foo 而不抛出异常。现在我想测试一个无法识别的 foo 类型是否会导致抛出异常。
为此,我必须模拟一个枚举,并且已经看到了此处概述的解决方案: Mocking Java enum to add a value to test fail case
我也知道可以使用 powermock,但我真的很喜欢 spock,因为我发现它非常轻巧,因此正在寻找使用 spock 的解决方案。
我认为这样的事情可能会奏效:
def "An unexpected type of foo causes an exception to be thrown"() {
given:
Foo foo = Mock()
when:
subjectUnderTest.handleFoo foo
then:
thrown Exception
}
但是,这会失败并显示以下错误消息:
org.spockframework.mock.CannotCreateMockException: Cannot create mock for class com.Foo because Java mocks cannot mock final classes. If the code under test is written in Groovy, use a Groovy mock.
我想知道是否有人知道使用 spock 的方法,因为我在任何文档中都找不到解决方案。
编辑在下面的一些cmets之后,我觉得最好澄清一下我为什么要编写这些测试。
我在一个有很多开发人员的团队中工作,其中一个很可能会更新枚举。如果发生这种情况以使开发人员意识到他们需要添加逻辑来处理新的枚举类型,我希望测试失败。 为此,我编写了一个测试,迭代枚举可能具有的每个可能值,将其传递给方法并验证没有引发异常。现在,如果用户添加了一个新的枚举,这个测试将会失败,因为没有任何东西可以处理它,所以会(希望)抛出一个异常。
第二个测试(我正在努力编写的那个)是为了澄清默认逻辑按我的预期工作,并且实际上确实抛出了异常。在不创建我永远不想使用的枚举值的情况下,我能想到的唯一方法是模拟一个枚举,并测试如果未处理枚举值是否会引发异常。
代码如下:
枚举 Foo:
public enum Foo {
ONE, TWO;
}
处理foo的方法:
private void handleFoo(Foo foo) {
switch (foo) {
case ONE:
doEventOne();
break;
case TWO:
doEventTwo()
break;
default:
throw new IllegalArgumentException("Do not know how to handle " + foo);
}
【问题讨论】:
-
请提供样品测试。
-
@Opal 我已经添加了上面的示例测试。
-
我们需要模拟枚举吗?
-
@Ramsharan,好问题!
-
@BenGreen 您能否发布您尝试使用模拟枚举编写测试的实际代码逻辑?
标签: java unit-testing groovy enums spock