@Test
@DisplayName("createTodoList(): todoList 컨트롤러을 이용해 글 생성에 성공하기")
void test1() throws Exception{
//given
Member member = memberRepository.findById("testUser").get();
String url = "/api/todolist";
String title = "abc";
String content = "test1";
final AddTodoListDTO userRequest = new AddTodoListDTO(member,title,content);
String requestBody = objectMapper.writeValueAsString(userRequest);
//객체를 JSON으로 직렬화 한다. (Post로 오는 요청은 JSON으로 오기때문에 직렬화 해줘야함.)
//when
ResultActions result = mockMvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody));
//mock을 통해 JSON를 보냄.
//then
result.andExpect(status().isCreated());
List<TodoBoard> todoBoardList = todoBoardRepository.findAll();
assertThat(todoBoardList.size()).isEqualTo(1);
assertThat(todoBoardList.get(0).getContent()).isEqualTo(content);
}
Post요청을 통한 글 작성 기능 테스트중 문제가 발생했다. (member가 제대로 넘어가지않는 모양..)
디버깅을 진행해 원인 파악에 들어갔다..
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member writer;
LazyInitializationException
- 지연 로딩이 적용중이고, 게시물 생성을위해 member 객체를 참조해야하는 상황에서 member객체 참조가되야하는데 참조가 되지 않고있다.
(게시물 작성에는 member객체가 필요하다.)
문제는 테스트 코드상에서의 트랙잭션 범위였다.
- defer-datasource-initialization: true
기능을 이용해 data.sql에 테스트 데이터를 db에 생성한 후 memberRepository.findById("testUser")를 이용해 testUser를 반환받기로 생각했는데 이 부분에서 당연하게 memberRepository는 JPARepository의 구현체니까 따로 @Transactional을 하지 않아도 commit이 될거라 생각했다.
물론 commit이 되긴했지만 @Transactional은 테스트 케이스내에서는 데이터 베이스의 무결성을 위해 commit 후에 rollback이 진행됬고rollback이 진행되어 member변수가 참조되지 않아 LazyInitializationException 이 발생된듯 싶다.
해결방안
@Trasactional 을 테스트 메서드단위에 적용시켜 테스트가 종료되고 나서 rollback되도록 적용하니 정상적으로 테스트가 성공했다.
'Error' 카테고리의 다른 글
테스트 환경에서 Cookie를 다루거나 검증해야할때 (0) | 2023.12.08 |
---|---|
스프링 이미지 출력 문제 (0) | 2023.10.06 |
독립적인 테스트 환경 구성하기 (0) | 2023.09.13 |
fetch API 사용 과 DTO의 기본생성자 Issue (0) | 2023.08.31 |
JPA 양방향 참조관계 무한 루프 [Infinite recursion] (0) | 2023.08.12 |