嘲笑Java枚举添加一个值来测试失败案例

我有一个枚举开关或多或少像这样:

public static enum MyEnum {A, B}

public int foo(MyEnum value) {
    switch(value) {
        case(A): return calculateSomething();
        case(B): return calculateSomethingElse();
    }
    throw new IllegalArgumentException("Do not know how to handle " + value);
}

我想要测试覆盖所有行,但由于代码需要处理所有可能性,因此在交换机中没有相应的case语句的情况下,我无法提供值。

扩展枚举以添加额外的值是不可能的,只是嘲笑equals方法返回false将不起作用,因为生成的字节码使用窗帘后面的跳转表来转到正确的案例...所以我已经认为PowerMock或许可以实现一些黑魔法。

谢谢!

编辑

因为我拥有枚举,所以我认为我可以在值中添加一个方法,从而完全避免切换问题; 但我仍然留下这个问题,因为它仍然很有趣。


这是一个完整的例子。

代码几乎和你原来的一样(只是简化了更好的测试验证):

public enum MyEnum {A, B}

public class Bar {

    public int foo(MyEnum value) {
        switch (value) {
            case A: return 1;
            case B: return 2;
        }
        throw new IllegalArgumentException("Do not know how to handle " + value);
    }
}

这里是完整代码覆盖的单元测试,该测试适用于Powermock(1.4.10),Mockito(1.8.5)和JUnit(4.8.2):

@RunWith(PowerMockRunner.class)
public class BarTest {

    private Bar bar;

    @Before
    public void createBar() {
        bar = new Bar();
    }

    @Test(expected = IllegalArgumentException.class)
    @PrepareForTest(MyEnum.class)
    public void unknownValueShouldThrowException() throws Exception {
        MyEnum C = PowerMockito.mock(MyEnum.class);
        Whitebox.setInternalState(C, "name", "C");
        Whitebox.setInternalState(C, "ordinal", 2);

        PowerMockito.mockStatic(MyEnum.class);
        PowerMockito.when(MyEnum.values()).thenReturn(new MyEnum[]{MyEnum.A, MyEnum.B, C});

        bar.foo(C);
    }

    @Test
    public void AShouldReturn1() {
        assertEquals(1, bar.foo(MyEnum.A));
    }

    @Test
    public void BShouldReturn2() {
        assertEquals(2, bar.foo(MyEnum.B));
    }
}

结果:

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.628 sec

@Melloware

...执行switch()语句的代码java抛出一个java.lang.ArrayIndexOutOfBounds ...

我有着同样的问题。 使用新的Enum作为测试类中的第一个运行测试。 我用这个问题创建了一个bug:https://code.google.com/p/powermock/issues/detail?id=440


而不是使用一些激进的字节码操作来启用一个测试来foo的最后一行,我将删除它并依靠静态代码分析来代替。 例如,IntelliJ IDEA具有“未使用大小写的Enum switch语句”代码检查,如果缺少某个case它将为foo方法发出警告。

链接地址: http://www.djcxy.com/p/88657.html

上一篇: Mocking Java enum to add a value to test fail case

下一篇: C++ TerminateProcess function