java 如何模拟 ResourceBundle.getString()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25030576/
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
How to mock ResourceBundle.getString()?
提问by BetaRide
I'm failing to mock ResourceBundle.getString()
.
我没有嘲笑ResourceBundle.getString()
。
This is my code:
这是我的代码:
ResourceBundle schemaBundle = Mockito.mock(ResourceBundle.class);
Mockito.when(schemaBundle.getString("testKey_testPropertyName_ect")).thenReturn("testString1");
This gives the following exception on the second line:
这在第二行给出了以下异常:
java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByMockitoWithCGLIB$e259f03, key testKey_testPropertyName_ect
at java.util.ResourceBundle.getObject(ResourceBundle.java:374)
at java.util.ResourceBundle.getString(ResourceBundle.java:334)
at com.foo.bar.resource.PropertyResourceTest.testGet(PropertyResourceTest.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.accessMockito.doReturn("testString1").when(schemaBundle).getString("testKey_testPropertyName_ect");
0(ParentRunner.java:42)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
To me this looks as if schemaBundle
isn't mocked at all. But the debuger clearly shows, that the instance is wrapped by mockito.
在我看来,这似乎schemaBundle
根本没有被嘲笑。但是调试器清楚地表明,该实例是由 mockito 包装的。
I also tried with
我也试过
import java.util.ResourceBundle;
ResourceBundle dummyResourceBundle = new ResourceBundle() {
@Override
protected Object handleGetObject(String key) {
return "fake_translated_value";
}
@Override
public Enumeration<String> getKeys() {
return Collections.emptyEnumeration();
}
};
// Example usage
when(request.getResourceBundle(any(Locale.class))).thenReturn(dummyResourceBundle)
but this returns the same exception.
但这会返回相同的异常。
Any idea what's wrong?
知道出了什么问题吗?
采纳答案by ccpizza
Instead of mocking you can create a dummy ResourceBundle implementation, and then pass it in .thenReturn(resourceBundle)
:
您可以创建一个虚拟的 ResourceBundle 实现,而不是模拟,然后将其传入.thenReturn(resourceBundle)
:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ ResourceBundle.class })
public class ResourceBundleTest {
@Test
public void getStringByPowerMock() throws Exception {
ResourceBundle resourceBundle = PowerMockito.mock(ResourceBundle.class);
Mockito.when(resourceBundle.getString(Mockito.anyString())).thenReturn("Hello world....");
System.out.println(resourceBundle.getString("keyword"));
}
}
If you need the actual keys and values, then you'll need to provide an implementation for getKeys()
, e.g. a hashmap for storage and key lookup.
如果您需要实际的键和值,那么您需要为 提供一个实现getKeys()
,例如用于存储和键查找的哈希图。
回答by user2049200
You'll find an example of solution below :
您将在下面找到解决方案的示例:
ReviewEChannelApplicationMBean = spy(new ReviewEChannelApplicationMBean(){
@Override
public ResourceBundle getBundle(FacesContext fcContext) {
return TestDataBuilder.getResourceBundle();
}
});
回答by Julius Musseau
I figured out a way to mock ResourceBundle by subclassing ResourceBundle.Control. My answer is here:
我想出了一种通过继承 ResourceBundle.Control 来模拟 ResourceBundle 的方法。我的答案在这里:
https://stackoverflow.com/a/28640458/290254
https://stackoverflow.com/a/28640458/290254
I prefer to avoid the dynamic bytecode rewriting (to remove final) of PowerMock, JMockit and friends, since Jacoco and other things seem to hate it.
我更喜欢避免 PowerMock、JMockit 和朋友的动态字节码重写(删除 final),因为 Jacoco 和其他东西似乎讨厌它。
回答by Kumar Abhishek
@Powermockito did not worked as ResourceBundle.class have static final methods which were not easy to mock.
@Powermockito 不起作用,因为 ResourceBundle.class 具有不容易模拟的静态最终方法。
I tried.
我试过。
In the Main Class extract your method inside another public method, and then overide it with implementaion.
在主类中,将您的方法提取到另一个公共方法中,然后使用 implementationaion 覆盖它。
Here ReviewEChannelApplicationMBean is my Controller, where i overrriden the getBundle.
这里 ReviewEChannelApplicationMBean 是我的控制器,我在这里覆盖了 getBundle。
public class TestDataBuilder {
public static ResourceBundle getResourceBundle() {
return new ListResourceBundle(){
@Override
protected Object[][] getContents() {
return contents;
}
private Object[][] contents = {
{"test1","01"},
{"test2","01"},
{"test3","01"},
{"test4","01"}
};
};
}
}
//This Class i my TestDataBuilder using ListResourceBundle
//这个类是我的 TestDataBuilder 使用 ListResourceBundle
##代码##