我正在尝试模拟对最终方法ResourceBundle.getString()
的调用。使用PowerMock 1.4.12和EasyMock 3.1,呼叫不会被嘲笑;相反,调用“真实”方法。
我的测试班:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class)
public class TestSuite {
@Before
public void setUp() throws Exception {
ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class);
expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue");
PowerMock.replay(resourceBundleMock);
beanBeingTested.setMessages(resourceBundleMock);
}
...
}
BeanBeingTested中的代码:
private ResourceBundle messages;
...
String label = messages.getString(BundleConstants.QUEUE);
错误讯息:
java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue
at java.util.ResourceBundle.getObject(ResourceBundle.java:384)
at java.util.ResourceBundle.getString(ResourceBundle.java:344)
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87)
当我逐步完成测试用例时,调试器将beanBeingTested.messages
的类型显示为“类java.util.ResourceBundle的EasyMock”,因此正确注入了mock。 (另外,在设置过程中,getString()
来电中expect()
的来电没有错误。
使用普通模拟而非模拟,我收到以下错误:
java.lang.AssertionError:
Unexpected method call handleGetObject("Queue"):
getString("Queue"): expected: 1, actual: 0
知道我做错了吗?
感谢。
答案 0 :(得分:3)
您正在使用EasyMock创建实例。相反,在使用静态方法时,必须模拟类(使用PowerMock)。
它应该像那样(用EasyMock 3.0和PowerMock 1.5进行测试):
@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class)
public class TestSuite {
@Before
public void setUp() throws Exception {
// mock the class for one method only
PowerMock.mockStaticNice(ResourceBundle.class, "getString");
// define mock-behaviour on the class, when calling the static method
expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue");
// start the engine
PowerMock.replayAll();
}
}
(我知道这个问题已经有几个月了,但它可能对其他人有所帮助)
答案 1 :(得分:1)
尝试使用:
@PrepareForTest({ResourceBundle.class, BeanBeingTested.class})
只有在PrepareForTest中使用ResourceBundle时,模拟在直接从单元测试方法调用时才会起作用,但是当从BeanBeingTested调用时,您将获得正在使用的实际方法。
此领域缺乏Powermock文档。
答案 2 :(得分:0)
为什么要打扰模拟对资源包的调用?一般来说,我试图避免模仿java的细节,比如ArrayList,Date等。资源包(和MessageFormat.format())或多或少都属于同一类别。它们通常以字符串为基础进行操作,如果这些事情被破坏或改变其行为足以打破测试,那肯定是我想知道的事情:)
让他们抓住字符串(可能是在UI中设置,也许是在之后。不要打扰断言返回的值,因为你不想编辑捆绑包来破坏你的测试。如果string在一个模拟UI组件上设置,这是anyObject(String.class)的一个好地方,它正确地表达了你(可能)实际上并不关心显示的特定字符串的事实。
当测试由于缺少消息密钥而失败时,我也认为这是一个好处。我想知道。