繁体   English   中英

使用资源包的单元测试静态方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM