Mockito 和 ReloadableResourceBundleMessageSource 不能很好地结合在一起吗?
Mockito and ReloadableResourceBundleMessageSource doesn't go well together?
我有这个简单的测试,它甚至不是测试,因为我只是想模拟消息源。
我收到此错误:
org.springframework.context.NoSuchMessageException: No message
found under code '' for locale 'null'.
其他人可以验证此行为吗?
这是我设置的最小 spring 启动框架测试,因为 ReloadableResourceBundleMessageSource
在另一个项目中不起作用,所以我想我会尽可能以最小的单元尝试它。
@RunWith(MockitoJUnitRunner.class)
public class DemoApplicationTests {
@Test
public void contextLoads() {
ReloadableResourceBundleMessageSource messageSource =
mock(ReloadableResourceBundleMessageSource.class);
when(
messageSource.getMessage(
anyString(),
any(Object[].class),
any(Locale.class)
)
).thenReturn("returnValue");
System.out.println("test");
}
}
这是我得到的错误:
org.springframework.context.NoSuchMessageException: No message
found under code '' for locale 'null'.
at org.springframework.context.support.AbstractMessageSource.getMessage(
AbstractMessageSource.java:159)
at com.example.DemoApplicationTests.contextLoads(
DemoApplicationTests.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at ....
....
....
....
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(
JUnit4IdeaTestRunner.java:117)
at com.intellij.rt.execution.junit.JUnitStarter.
prepareStreamsAndStart(
JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(
JUnitStarter.java:74)
在我看来,它无法正确模拟它。我也试过模拟 MessageSource
界面但无济于事。
正如大卫华莱士所说:
Mockito 无法存根 "final" 方法,并且由于 'getMessage' 被声明为最终的,您无法模拟它。
我不想使用 PowerMock,我解决了创建一个真正的 ReloadableResourceBundleMessageSource bean 的问题,并将其注入我想测试的 class
// create the real bean
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(-1);
messageSource.setBasenames("classpath:conf-test/messages"); // this folder is just for testing and it contains a messages_en.properties file
// inject the bean into the class I wanted to test
ReflectionTestUtils.setField(service, "messageSource", messageSource);
我发现 work-around 在这种情况下模拟 final 方法的 mockito 限制。
我没有模拟,而是在构建 class 之后像这样设置它:
ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
bundleMessageSource.setUseCodeAsDefaultMessage(true);
Return whether to use the message code as default message instead of
throwing a NoSuchMessageException. Useful for development and
debugging. Default is "false".
Final 方法无法模拟。所以我写了一个这样的解决方案。
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setUseCodeAsDefaultMessage(true);
ReflectionTestUtils.setField(service, "messageSource", messageSource);
我有这个简单的测试,它甚至不是测试,因为我只是想模拟消息源。
我收到此错误:
org.springframework.context.NoSuchMessageException: No message
found under code '' for locale 'null'.
其他人可以验证此行为吗?
这是我设置的最小 spring 启动框架测试,因为 ReloadableResourceBundleMessageSource
在另一个项目中不起作用,所以我想我会尽可能以最小的单元尝试它。
@RunWith(MockitoJUnitRunner.class)
public class DemoApplicationTests {
@Test
public void contextLoads() {
ReloadableResourceBundleMessageSource messageSource =
mock(ReloadableResourceBundleMessageSource.class);
when(
messageSource.getMessage(
anyString(),
any(Object[].class),
any(Locale.class)
)
).thenReturn("returnValue");
System.out.println("test");
}
}
这是我得到的错误:
org.springframework.context.NoSuchMessageException: No message
found under code '' for locale 'null'.
at org.springframework.context.support.AbstractMessageSource.getMessage(
AbstractMessageSource.java:159)
at com.example.DemoApplicationTests.contextLoads(
DemoApplicationTests.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at ....
....
....
....
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(
JUnit4IdeaTestRunner.java:117)
at com.intellij.rt.execution.junit.JUnitStarter.
prepareStreamsAndStart(
JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(
JUnitStarter.java:74)
在我看来,它无法正确模拟它。我也试过模拟 MessageSource
界面但无济于事。
正如大卫华莱士所说:
Mockito 无法存根 "final" 方法,并且由于 'getMessage' 被声明为最终的,您无法模拟它。
我不想使用 PowerMock,我解决了创建一个真正的 ReloadableResourceBundleMessageSource bean 的问题,并将其注入我想测试的 class
// create the real bean
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(-1);
messageSource.setBasenames("classpath:conf-test/messages"); // this folder is just for testing and it contains a messages_en.properties file
// inject the bean into the class I wanted to test
ReflectionTestUtils.setField(service, "messageSource", messageSource);
我发现 work-around 在这种情况下模拟 final 方法的 mockito 限制。
我没有模拟,而是在构建 class 之后像这样设置它:
ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
bundleMessageSource.setUseCodeAsDefaultMessage(true);
Return whether to use the message code as default message instead of throwing a NoSuchMessageException. Useful for development and debugging. Default is "false".
Final 方法无法模拟。所以我写了一个这样的解决方案。
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setUseCodeAsDefaultMessage(true);
ReflectionTestUtils.setField(service, "messageSource", messageSource);