Java 为Junit测试创建模拟枚举值时出错

Java 为Junit测试创建模拟枚举值时出错,java,junit,enums,powermock,Java,Junit,Enums,Powermock,我有一个枚举类:- public enum Action { LOGGED_IN("logged_in"), LOGGED_OUT("logged_out"), private final String action; /** * @param action */ private Action(String action) { this.action = action; } /**Fetches t

我有一个枚举类:-

public enum Action {
    LOGGED_IN("logged_in"), 
    LOGGED_OUT("logged_out"),
    private final String action;

    /**
     * @param action
     */
    private Action(String action) {
        this.action = action;
    }

    /**Fetches the action.
     * @return String action
     */
    public String getAction() {
        return this.action;
    }
}
我正在编写下面的Junit来模拟这个枚举类,这样我就可以为这个操作添加另一个枚举值,以便进行Junit测试

@RunWith(PowerMockRunner.class)
public class TestClass{

    public Action action;

@Test
    @PrepareForTest(Action.class)
    public void testgetFeatureIdNull() NoSuchFieldException, SecurityException {
        Action dummy = PowerMockito.mock(Action.class);
        Field value=Action.class.getDeclaredField("value");
        value.setAccessible(true);
        Whitebox.setInternalState(dummy, "value", "dummy");
        Whitebox.setInternalState(dummy,"ordinal", 2);
        request = "{" + "   opportunityNumber: 45," + " id: 1," + "   " + " s: {" + "   id: 23"
                + " }" + "}";
        action = Action.LOGGED_IN;
        assertEquals(null, PatternGenertor.getFeatureid(dummy, request));
    }
运行此代码时,我遇到以下错误:-

java.lang.NoSuchFieldException: value
    at java.lang.Class.getDeclaredField(Unknown Source)

有人能告诉我哪里做错了吗?

我能够模拟我的枚举,并使用下面的代码向它添加一个伪值

@Test
    @PrepareForTest(Action.class)
    public void testgetFeatureIdNull() throws  NoSuchFieldException, SecurityException, NoSuchMethodException {
        Action dummy = PowerMockito.mock(Action.class);
        Method value=Action.class.getSuperclass().getDeclaredMethod("ordinal");
        value.setAccessible(true);
        Field value1=Action.class.getSuperclass().getDeclaredField("name");
        value1.setAccessible(true);

        Whitebox.setInternalState(dummy, "name", "dummy");
        Whitebox.setInternalState(dummy,"ordinal", 2);
        PowerMockito.mockStatic(Action.class);

        PowerMockito.when(Action.values()).thenReturn(new Action[]{Action.LOGGED_IN,Action.LOGGED_OUT, dummy});

        request = "{" + "   opportunityNumber: 34," + " id: 1," + "   " + " s: {" + "   id: 23"
                + " }" + "}";
        assertNull(PatternGenertor.getFeatureid(dummy, request));
    }

我可能会在这里给出一个不太适合某个问题的答案,但无论如何我都会尝试。在我看来,您不应该真的向Enum添加值。这对于枚举来说毫无意义

枚举是包含程序使用的可能值列表的内容。 如果你在mock中添加更多的值,就像说-嘿,我不想再测试我的代码了,但我想测试一些在现实生活中从未发生过的事情。这听起来不对

相反,您可能应该问问自己,您到底想要测试什么,并更改测试的逻辑,以便它只依赖于从enum返回的实际值

我甚至可以说,在我的实践中,我从未用任何工具模拟过enum,尽管它可能对答案没有帮助:


此外,您现在必须使用PowerMock,这是一个非常沉重且令人不快的工具,我们的许多同事认为,只有当您必须测试一个没有人愿意更改的遗留代码时,才应该使用它。

是什么让您认为枚举类的超类(即枚举)有一个名为value的字段?枚举类的no value字段…为什么要向枚举添加第三个值?当然,从测试的角度来看,测试代码如何仅使用枚举中的两个值而不是三个值更有意义?您应该测试代码的方式,不是代码可能的方式。我想要第三个值,因为我想测试如果用户提供一些在操作枚举中不存在的伪数据,代码的行为……这也是我需要涵盖的场景之一,因为在这种情况下,被测试的方法将返回空值。但这是完全不同的场景!测试如果用户给出错误的输入会发生什么与更改实际枚举中的值不是一回事。此测试完全不能证明程序的行为。如果我在工作过程中检查此代码,我会要求您将其从代码库中删除。