Java Mockito和ReloadableResourceBundleMessageSource不';你们相处不好吗?

Java Mockito和ReloadableResourceBundleMessageSource不';你们相处不好吗?,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,我有一个简单的测试,它甚至不是一个测试,因为我只是试图模拟messagesource 我得到了这个错误: org.springframework.context.NoSuchMessageException: No message found under code '' for locale 'null'. 其他人能验证这种行为吗 这是我设置的一个最小spring引导框架测试,因为另一个项目中没有ReloadableResourceBundleMessageSource,所以我想我将在尽可能

我有一个简单的测试,它甚至不是一个测试,因为我只是试图模拟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
界面,但没有成功。

正如David Wallace所说:


Mockito不能存根“final”方法,因为“getMessage”声明为final,所以不能对其进行模拟。

我不想使用PowerMock,我解决了创建一个真正可重新加载的ResourceBundleMessageSource bean的问题,并将其注入到我想要测试的类中

// 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);

在本例中,我发现了一个解决mockito限制的方法,可以模拟final方法

我没有模仿,而是在构建类后将其设置为:

ReloadableResourceBundleMessageSource bundleMessageSource = new ReloadableResourceBundleMessageSource();
bundleMessageSource.setUseCodeAsDefaultMessage(true);
根据报告:

返回是否将消息代码用作默认消息,而不是 正在引发NoSuchMessageException。有利于发展和发展 调试。默认值为“false”


最终的方法不能模仿。所以我写了一个这样的解决方案

    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setUseCodeAsDefaultMessage(true);
    ReflectionTestUtils.setField(service, "messageSource", messageSource);

我不知道你的问题是什么,但无法存根
getMessage
的原因是因为它在
AbstractMessageSource
中声明为
final
,它是
ReloadableResourceBundleMessageSource
的超类。Mockito无法存根最终方法。谢谢,这就解释了!你的回答基本上是抄袭了@DavidWallace的评论。您可以通过提及PowerMock来扩展您的答案,PowerMock能够证明这是我评论的副本这一事实并不意味着它是错误的。奥德贝克发布这篇文章是正确的,而我太懒了。他/她甚至正确地归因于此。这不值得一票否决。谢谢大卫W@RomanVottner:我不知道PowerMock,如果我知道Mockito和final方法的问题,我可能根本不会问这个问题。反正我们可以得到消息,因为上面只返回消息代码?