简体   繁体   中英

Unit testing of Spring Boot application with Freemarker throws NoSuchMessageException

I am developing a Spring Boot web application that uses FreeMarker as the template engine.
I have 1.4.0 version of spring-boot and use auto-configuration, there is internationalization and few messages.properties for different locales. Anything works fine, depending of current locale application returns HTML generated by FreeMarker and filled with strings from appropriate .properties .

But when I try to test controller which works correctly I get NoSuchMessageException , FreeMarker can't find strings in messages.properties .

I implemented unit testing according with the following article Testing improvements in Spring Boot 1.4

Here is code of test:

@RunWith(SpringRunner.class)
@WebMvcTest(VideoController.class)
public class VideoControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    VideoService videoService;

    @Test
    public void showVideoSection() throws Exception {
        ResultActions result = mockMvc.perform(MockMvcRequestBuilders.get("/video"));
        result.andExpect(MockMvcResultMatchers.view().name("video"));
    }

}

And here is code of tested method:

 @RequestMapping(value = "/video", method = RequestMethod.GET)
 public String showVideoSection(Model model) {
    model.addAttribute("currentLanguage", LocaleContextHolder.getLocale().getLanguage());
    long numberOfAvailableVideos = videoService.getNumberOfAvailableVideos();
    if (numberOfAvailableVideos > 0) {
        if (numberOfAvailableVideos >= 5) {
            model.addAttribute("videoList", videoService.getPageOfVideos(0, 5));
        } else {
            model.addAttribute("videoList", videoService.getPageOfVideos(0, (int)numberOfAvailableVideos));
        }
    } 
    return "video";
}

Below is stack-trace:

2016-08-10 17:07:32.210 ERROR 5504 --- [main] freemarker.runtime: Error executing FreeMarker template

freemarker.core._TemplateModelException: Java method "org.springframework.web.servlet.support.RequestContext.getMessage(String)" threw an exception when invoked on org.springframework.web.servlet.support.RequestContext object "org.springframework.web.servlet.support.RequestContext@4da6d664"; see cause exception in the Java stack trace.

----
FTL stack trace ("~" means nesting-related):
- Failed at: ${springMacroRequestContext.getMessag...  [in template "spring.ftl" in macro "message" at line 28, column 22]
- Reached through: @spring.message code="nav.video"  [in template "common.ftl" in macro "body" at line 65, column 49]
- Reached through: @common.body mode="video" language="$...  [in template "video.ftl" at line 7, column 5] 
~ Reached through: #nested  [in template "common.ftl" in macro "html" at line 12, column 5] 
~ Reached through: @common.html  [in template "video.ftl" at line 5, column 1]
----

...
...
Caused by: org.springframework.context.NoSuchMessageException: No message found under code 'nav.video' for locale 'en'.
at org.springframework.context.support.DelegatingMessageSource.getMessage(DelegatingMessageSource.java:69) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getMessage(AbstractApplicationContext.java:1254) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:711) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:677) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1458) ~[freemarker-2.3.25-incubating.jar:2.3.25]
at freemarker.ext.beans.ReflectionCallableMemberDescriptor.invokeMethod(ReflectionCallableMemberDescriptor.java:56) ~[freemarker-2.3.25-incubating.jar:2.3.25]
at freemarker.ext.beans.MemberAndArguments.invokeMethod(MemberAndArguments.java:51) ~[freemarker-2.3.25-incubating.jar:2.3.25]
at freemarker.ext.beans.OverloadedMethodsModel.exec(OverloadedMethodsModel.java:61) ~[freemarker-2.3.25-incubating.jar:2.3.25]
... 79 common frames omitted

My best guess is that MessageSourceAutoConfiguration needs to run in order to correctly handle message.properties files. This probably isn't the case at the moment (and something we should probably fix in Spring Boot 1.4.1).

You might be able to work around the issue by adding a src/test/resources/META-INF/spring.factories file with the following content:

org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc=\
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration

I've raised https://github.com/spring-projects/spring-boot/issues/6608 to fix this. If you have a sample project that replicates the issue could you please attach a link to the bug report.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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