Java 如何使用 JUnit、EasyMock 或 PowerMock 模拟静态最终变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9697531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:18:12  来源:igfitidea点击:

How to mock a static final variable using JUnit, EasyMock or PowerMock

javaunit-testingjuniteasymockpowermock

提问by Prince

I want to mock a static final variable as well as mock a i18n class using JUnit, EasyMock or PowerMock. How do I do that?

我想模拟静态最终变量以及使用 JUnit、EasyMock 或 PowerMock 模拟 i18n 类。我怎么做?

回答by Antoine

Is there something like mockinga variable? I would call that re-assign. I don't think EasyMock or PowerMock will give you an easy way to re-assign a static finalfield (it sounds like a strange use-case).

有没有类似模拟变量的东西?我会称之为重新分配。我不认为 EasyMock 或 PowerMock 会给你一个简单的方法来重新分配一个static final字段(这听起来像是一个奇怪的用例)。

If you want to do that there probably is something wrong with your design: avoid static final(or more commonly global constants) if you know a variable may have another value, even for test purpose.

如果你想这样做,你的设计可能有问题:避免static final(或更常见的全局常量)如果你知道一个变量可能有另一个值,即使是为了测试目的。

Anyways, you can achieve that using reflection (from: Using reflection to change static final File.separatorChar for unit testing?):

无论如何,您可以使用反射来实现这一点(来自:使用反射更改静态最终 File.separatorChar 以进行单元测试?):

static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    // remove final modifier from field
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

    field.set(null, newValue);
}

Use it as follows:

使用方法如下:

setFinalStatic(MyClass.class.getField("myField"), "newValue"); // For a String

Don't forget to reset the field to its original value when tearing down.

拆卸时不要忘记将字段重置为其原始值。

回答by cwash

It can be done using a combination of PowerMock features. Static mocking using the @PrepareForTest({...})annotation, mocking your field (I am using Mockito.mock(...), but you could use the equivalent EasyMock construct) and then setting your value using the WhiteBox.setInternalState(...)method. Note this will work even if your variable is private.

可以使用 PowerMock 功能的组合来完成。使用@PrepareForTest({...})注释进行静态模拟,模拟您的字段(我正在使用Mockito.mock(...),但您可以使用等效的 EasyMock 构造),然后使用该WhiteBox.setInternalState(...)方法设置您的值。请注意,即使您的变量是private.

See this link for an extended example: http://codyaray.com/2012/05/mocking-static-java-util-logger-with-easymocks-powermock-extension

有关扩展示例,请参阅此链接:http: //codyaray.com/2012/05/mocking-static-java-util-logger-with-easymocks-powermock-extension