Mockito模拟任何I18n实例创建的运行时

时间:2013-04-11 08:06:56

标签: java mockito

我有一个场景,就像我在代码中动态创建i18n对象实例一样。我使用以下代码:

public String getLocaleString(Locale locale, SlingHttpServletRequest request){
    final ResourceBundle bundle = request.getResourceBundle(locale);
    I18n i18n = new I18n(bundle);
    return i18n.get("local");
}

这里有语言环境,请求我嘲笑。但是i18n是动态创建的。所以我无法模仿i18n.get("local")

我尝试使用:

when(any(I18n.class).get("local")).thenReturn("localizedString")

但我无法做到。我在这一行得到NullPointerException。

我想用Mockito来嘲笑这个场景。你能帮帮我吗?感谢。

2 个答案:

答案 0 :(得分:2)

Mockito建议重构以解决这个https://code.google.com/p/mockito/wiki/MockingObjectCreation?ts=1332544670&updated=MockingObjectCreation

我通常会避免测试方法的内部结构。

但在某些情况下,我确实需要使用PowerMockito https://code.google.com/p/powermock/wiki/MockConstructor

答案 1 :(得分:1)

我认为不可能以这种方式使用any(),因为它是一个参数匹配器,你应该只用方法调用指定一个mock对象,例如:

when(mock(i18n).get("local")).thenReturn("localizedString");

我认为这可能是您NullPointerException的来源。

但是为了解决你的问题,我认为你有两个选择:

第一种是使用工厂创建I18n对象,然后模拟工厂:

...
private I18nFactory factory;
...

public String getLocaleString(Locale locale, SlingHttpServletRequest request){
    final ResourceBundle bundle = request.getResourceBundle(locale);
    I18n i18n = factory.get(bundle);
    return i18n.get("local");
}

然后在测试中,设置工厂以生成所需的对象:

// Mock I18n, locale, request etc...

final I18nFactory factory = mock(I18nFactory.class);
when(factory.get(bundle)).thenReturn(i81n);

// Assign 'factory' to your Controller(?)
controller.setI18nFactory(factory);

// act, assert etc...

第二种方法是设置localerequest模拟/对象,使new I18n(...)创建符合您期望的有效对象。

总的来说,我认为我更愿意使用第二种方法,特别是如果I18n是第三方类。虽然没有关于测试目标的更多信息,但这个答案有些推测。无论如何,我希望这会有所帮助。