繁体   English   中英

使用 MockMvc 和 AutoConfigureMockMvc 测试 Spring 启动 web 应用程序时发生 LazyInitializationException 的原因是什么

[英]What is the cause of LazyInitializationException when testing Spring Boot web app with MockMvc and AutoConfigureMockMvc

我正在尝试本教程中的一些单元测试 Spring Boot MVC 示例 - https://spring.io/guides/gs/testing-web/ 我的项目有 Spring 引导 MVC 和 JPA ( https://github.com/shankarps/SfgUdemyRecipes

测试的 Controller 检索与类别实体具有多对多映射的食谱实体列表。

@RequestMapping({"", "/", "/index"})
public String getIndexPage(Model model){
    log.info("Getting all recipes");
    model.addAttribute("recipes", recipeService.getAllRecipes());
    return "index";
}

当 Spring 启动应用程序启动时,此 Controller 工作。 食谱列表显示在浏览器中。

这个带有 SpringBootTest 和 TestRestTemplate 的测试用例按预期工作。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IndexControllerHttpTest {
    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testIndexUrl(){
        String response = this.restTemplate.getForObject("http://localhost:"+port+"/", String.class);
    }
}

However, when I run a test case with MockMVC to test the Controller as a MVC object (with @AutoConfigureMockMvc), without the Http server, I get org.hibernate.LazyInitializationException Exception.

@SpringBootTest
@AutoConfigureMockMvc
public class IndexControllerMockMVCTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testIndexControllerView() throws Exception {
        this.mockMvc.perform(MockMvcRequestBuilders.get("/")).andExpect(status().isOk());
    }
}

这是完整的异常堆栈跟踪:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.shankar.sfg.recipes.recipes.domain.Category.recipes, could not initialize proxy - no Session    
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
    at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:327)
    at java.lang.String.valueOf(String.java:2994)

这看起来像是事务 scope 的问题。 任何人都可以帮助找到根本原因吗? 当作为完整的 Web 应用程序(使用@SpringBootTest)进行测试时,与在 MVC 层(@SpringBootTest 和 @AutoConfigureMockMvc)进行测试相比,测试 Spring 应用程序上下文需要哪些额外配置?

解决方案是将@Transactional 添加到调用Mock MVC 的Test 方法中。

@Test
@Transactional
public void testIndexControllerView() throws Exception {
    this.mockMvc.perform(MockMvcRequestBuilders.get("/")).andExpect(status().isOk());
}

这个答案处理单元测试 JPA 存储库 object 的类似问题。

LazyInitializationException:无法初始化代理 - 没有 Session

我还不确定为什么在没有 HTTP 服务器的情况下测试 controller 时需要事务 scope。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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