[英]Unit testing static method which uses a resource bundle
我已经阅读了很多有关使用Powermock和Mockito的文章,并尝试了许多不同的方法,但是我仍然无法找出对以下静态方法进行单元测试的方法。
public static Map<String, String> getEntries() {
Map<String, String> myEntriesMap = new TreeMap<String, String>();
ResourceBundle myEntries = ResourceBundle.getBundle(ENTRIES_BUNDLE);
Enumeration<String> enumList = myEntries.getKeys();
String key = null;
String value = null;
while (enumList.hasMoreElements()) {
key = enumList.nextElement().toString();
value = myEntries.getString(key);
myEntriesMap.put(key, value);
}
return myEntriesMap;
}
该代码是(遗留)类的一部分,该类包含大约30个这样的静态方法,并且重构并不是真正的选择。 类似地,在其他一些静态方法中,正在检索DBconnections。
例如:如何模拟资源包ENTRIES_BUNDLE并对该方法进行单元测试? 我正在寻找一种可以普遍应用于所有静态方法的模式。
使用ResourceBundle.getBundle(String,ResourceBundle.Control)获取ResourceBundle可以为给定的String缓存一个包。 您可以将ResourceBundle.Control子类化,以提供您想要的任何类型的捆绑包。
@Test
public void myTest()
{
// In your Test's init phase run an initial "getBundle()" call
// with your control. This will cause ResourceBundle to cache the result.
ResourceBundle rb1 = ResourceBundle.getBundle( "blah", myControl );
// And now calls without the supplied Control will still return
// your mocked bundle. Yay!
ResourceBundle rb2 = ResourceBundle.getBundle( "blah" );
}
这是控件的子类:
ResourceBundle.Control myControl = new ResourceBundle.Control()
{
public ResourceBundle newBundle( String baseName, Locale locale, String format,
ClassLoader loader, boolean reload )
{
return myBundle;
}
};
这是模拟ResourceBundle的一种方法(根据需要留给读者的单元测试,将键/值填充到TreeMap中):
ResourceBundle myBundle = new ResourceBundle()
{
protected void setParent( ResourceBundle parent )
{
// overwritten to do nothing, otherwise ResourceBundle.getBundle(String)
// gets into an infinite loop!
}
TreeMap<String, String> tm = new TreeMap<String, String>();
@Override
protected Object handleGetObject( String key )
{
return tm.get( key );
}
@Override
public Enumeration<String> getKeys()
{
return Collections.enumeration( tm.keySet() );
}
};
您不需要模拟ResourceBundle.getBundle
方法。 只需在测试源树中的适当位置创建一个“ .properties”文件即可。 这仍然是一个非常好的和有用的单元测试。
我们有一个类似的问题,它在模拟ResourceBundle.getString()方法。
java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByMockitoWithCGLIB$$e9ea44f0, key name
我们的问题是该方法是最终方法,这使得mockito无法模拟该方法。
相反,我们使用了以下灵魂: https : //code.google.com/p/powermock/wiki/MockSystem
请注意,@PrepareForTest({ClassThatCallsTheSystemClass.class})不是ResourceBundle类!
如果您使用以下库:mockito-all和jmockit,请执行以下步骤:
假设您要从xxxx.class模拟方法yyyy
@MockClass(realClass = xxxx.class)
public static class MyClass {
@Mock
public static void yyyy(){
......
}
}
在您的测试中:
@Test
public void test() {
Mockit.setUpMock(MyClass.class);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.