使用Mockito模拟私有静态final String

时间:2016-05-16 02:42:48

标签: java testing junit mockito

我很难在类中模拟私有静态final String字段。这是我的java示例代码:

public class Fruit {
private static final String FRUIT = "apple";

public void getFruit() {
    System.out.println("I like " + FRUIT);
}

}

我用Mockito来模拟FRUIT变量,这样我就可以将FRUIT的值从“apple”改为“mango”。为此,这是我的测试:

public class FruitTest {
@Test
public void testFruit() throws NoSuchFieldException, SecurityException, Exception {
    setFinalStatic(Fruit.class.getDeclaredField("FRUIT"), "mango");
    Fruit fruit = new Fruit();
    fruit.getFruit();
}

static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}

}

我在期待System.out.println("I like " + FRUIT); 它会打印芒果,但它仍在打印苹果。我真的很感激,如果有人能帮我这个只使用MOCKITO而不是PowerMock等。

4 个答案:

答案 0 :(得分:0)

编译时常量可以由javac内联进行优化。如果你改变你的Fruit课程:

public static class Fruit {         public static final String FRUIT = getFruit();

    public static String getFruit() {
        return "apple";
    }



}

它将显示结果芒果 setFinalStatic(Fruit.class.getField(" FRUIT")," mango"); 的System.out.println(Fruit.FRUIT);

答案 1 :(得分:0)

我最近调查了一些静态字段并且我认为如果没有powermock的帮助你不能做你正在尝试的事情。我也不确定你为什么要这样做。私有静态final字段是一个常量,并且不应该有一个真正的理由为什么你想要一个常量来改变。任何试图这样做的测试都试图测试错误的东西。

答案 2 :(得分:0)

更改常量的值不是一个好习惯。更重要的是,我认为是不可能的。但是,如果要更改字段的值,请删除修饰符“final”。

答案 3 :(得分:0)

单词 final 正好描述了创建String后不应该更改该值。这是您在Java中获取常量的方式。您的getFruit方法将始终返回“apple”。 Mockito对此不会帮助你。如果您正在测试此方法,则需要测试它始终返回“apple”。在你的情况下,方法是静态的是无关紧要的,因为你返回的是一个恒定的值。使用反射不是一个好主意,不仅仅因为它是一个非常糟糕的编码实践,而且因为你没有办法在未来正确管理变更。这是一个需要大量维护的侵入式代码,并且它总是生成几行,只是为了在运行时更改该方法,以便“可以对其进行测试”。总而言之,现实生活中的案例并不需要在单元测试中进行反思,除非当然有充分的理由或仅仅是架构需要改进。反思更像是一种学术性的东西,或者你正在构建自己的注射系统,模拟工具或任何需要这种编码的东西。