编程语言
首页 > 编程语言> > java – 有可能用Spock模拟枚举吗?

java – 有可能用Spock模拟枚举吗?

作者:互联网

我有一个switch语句来处理java enum foo,并使用spock编写一些groovy单元测试.我已经添加了一个测试,它验证当前是否处理了每种类型的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:无法为类com.Foo创建mock,因为Java模拟无法模拟最终类.如果测试中的代码是用Groovy编写的,请使用Groovy mock.

我想知道是否有人知道使用spock的方法,因为我找不到任何文档的解决方案.

编辑在下面的一些评论之后,我觉得最好澄清我为什么要编写这些测试.

我在一个有很多开发人员的团队中工作,很可能他们中的一个会更新枚举.我希望测试失败,如果这恰好使开发人员意识到他们需要添加逻辑来处理新的枚举类型.
为此,我编写了一个测试,迭代枚举可能具有的每个可能值,将其传递给方法并验证不会抛出异常.现在,如果用户添加了新的枚举,则此测试将失败,因为没有任何东西可以处理它,因此会(希望)抛出异常.

第二个测试(我正在努力编写的那个)是为了澄清默认逻辑的工作方式与我期望的一样,并且实际上异常会被抛出.在没有创建我永远不想使用的枚举值的情况下,我能想到这样做的唯一方法是模拟枚举,并测试如果不处理枚举值则抛出异常.

代码如下所示:

Enum 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);
}

解决方法:

以下规范将涵盖添加新枚举而不为其提供服务逻辑:

def 'no exception thrown for all enums'() {
    given:
    def service = new SampleService()

    when:
    service.handleFoo(se)

    then:
    noExceptionThrown()

    where:
    se << SampleEnum.values()
}

我试图编写一个测试,它将模拟枚举或在测试运行时添加另一个值,但现在失败了.稍后会回到它.

Spock不支持模拟枚举.

标签:java,enums,unit-testing,groovy,spock
来源: https://codeday.me/bug/20190609/1205609.html