Spring junit 测试模板可能不存在

Posted

技术标签:

【中文标题】Spring junit 测试模板可能不存在【英文标题】:Spring junit test template might not exist 【发布时间】:2017-06-15 10:17:57 【问题描述】:

首先,应用程序编译运行成功。

我尝试在 Spring Boot 中对我的控制器进行单元测试。我的测试控制器看起来像:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes =  Application.class )
@Rollback
@Transactional
@WebMvcTest(PasswordResetController.class)
public class PasswordResetControllerTest 
    @Autowired
    private MockMvc mvc;

    @Test
    public void getPasswordForgetView() throws Exception 
        this.mvc.perform(get("/password/forget"))
            .andExpect(status().isOk());
    

这样我得到以下异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "password-forget-html", template might not exist or might not be accessible by any of the configured Template Resolvers

如果我调试配置,我发现它通过了我的WebMvcConfig.class,我将模板指向/WEB-INF/templates/ 文件夹:

@Configuration
@ComponentScan(basePackages =  "com.tmp" )
public class WebMvcConfig extends WebMvcConfigurerAdapter 

    @Value("$mail.templates.cacheable")
    private boolean mailTemplatesCacheable;

    @Value("$html.templates.cacheable")
    private boolean htmlTemplatesCacheable;

    public static final String URL_RESOURCES = "/modules/**";
    public static final String PATH_RESOURCES = "/modules/";

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
        registry.addResourceHandler(URL_RESOURCES).addResourceLocations(PATH_RESOURCES);
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/login").setViewName("login");
    

    @Bean
    public TemplateResolver templateResolver() 
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setCacheable(htmlTemplatesCacheable);
        return templateResolver;
    

    @Bean
    public TemplateResolver mailResolver() 
        SpringResourceTemplateResolver result = new SpringResourceTemplateResolver();
        result.setPrefix("/WEB-INF/mail/");
        result.setSuffix(".html");
        result.setTemplateMode("HTML5");
        result.setCacheable(mailTemplatesCacheable);
        result.setOrder(2);
        result.setCharacterEncoding("UTF-8");
        return result;
    

    @Bean
    public SpringTemplateEngine templateEngine() 
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.addTemplateResolver(templateResolver());
        templateEngine.addTemplateResolver(mailResolver());
        templateEngine.addDialect("java8time", java8TimeDialect());
        templateEngine.addDialect("sec", springSecurityDialect());
        templateEngine.addDialect("layout", thymeleafLayoutDialect());
        return templateEngine;
    

    @Bean
    public ThymeleafViewResolver viewResolver() 
        ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
        thymeleafViewResolver.setTemplateEngine(templateEngine());
        thymeleafViewResolver.setCharacterEncoding("UTF-8");
        thymeleafViewResolver.setCache(false);
        return thymeleafViewResolver;
    

    // Dialect Beans
    ...

是的,文件夹中有模板。

有什么建议吗?提前致谢

【问题讨论】:

看起来WebMvcConfig 与测试无关。尝试将WebMvcConfig 直接添加到@ContextConfiguration 中。 如果我调试它,它会通过 WebMvcConfig 类 /WEB-INF/templates/ 在类路径中可见吗? 我认为是这样,因为应用程序正在运行。这只是关于测试用例 【参考方案1】:

首先,

你正在做一个切片测试来单独测试控制器,在这种情况下你不需要下面的配置 @ContextConfiguration(classes = Application.class )

试试:

@RunWith(SpringRunner.class)
@Transactional
@WebMvcTest(PasswordResetController.class)
public class PasswordResetControllerTest 
    @Autowired
    private MockMvc mvc;

    @Test
    public void getPasswordForgetView() throws Exception 
        this.mvc.perform(get("/password/forget"))
            .andExpect(status().isOk());
    

【讨论】:

感谢您的回复。我稍后需要整个应用程序(多数据库),这就是我声明上下文配置的原因。【参考方案2】:

从@eis 的评论中我得到了解决方案。注释WebMvcTestContextConfiguration 相互矛盾。我将课程更改为以下内容:

@RunWith(SpringRunner.class)
@SpringBootTest(classes =  Application.class )
public class PasswordResetControllerTest 

    @Autowired 
    private WebApplicationContext applicationContext;

    private MockMvc mockMvc;

    ...

    @Before  
    public void init()   
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.applicationContext).build();
    

现在它的工作就像一个魅力

【讨论】:

以上是关于Spring junit 测试模板可能不存在的主要内容,如果未能解决你的问题,请参考以下文章

Spring启动自定义登录:“登录”,模板可能不存在,或者任何配置的模板解析器都可能无法访问

Spring JPA Repository findAll 在 JUnit 测试中不返回任何数据

SpringBoot项目测试时出现程序包org.junit.runner不存在

解析模板时出错 [/],模板可能不存在或可能无法被任何已配置的模板解析器访问

Spring Boot 中的 Junit 测试不注入服务

解析模板 [users/list] 时出错,模板可能不存在或可能无法被任何已配置的模板解析器访问