일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준#BOJ#8012#한동이는영업사원
- 백준#boj#16932#모양만들기
- 백준#BOJ#1939#중량제한
- 백준#BOJ#14501#퇴사#브루트포스
- 백준#boj#12755
- 백준#BOJ#12865#평범한배낭
- 백준#BOJ#2615#오목
- Today
- Total
순간을 성실히, 화려함보단 꾸준함을
JPA metamodel must not be empty!!!!!! 본문
안녕하세요
오랜만에 찾아왔습니다.
현재 인프런 호돌맨님의 '요절복통 개발쇼' 강의를 보면서 개인적으로 공부하면서 코딩하고 있는데 마주쳤던 에러를 하나 소개해드릴려고 합니다.
JPA metamodel must not be empty!
입니다.
우리가 JPA 를 사용하여 프로젝트를 진행할때 도메인(엔티티) 를 생성할시에 '생성시간','수정시간' 을 필드로 정의하게 됩니다.
이때, 모든 도메인(엔티티)에 적용해야 하므로 @MappedSuperclass
를 사용해서 공통 클래스를 정의해주죠?
@Getter @Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
/**
* @MpaaerSuperclass : 공통 매핑 정보가 필요할때 사용한다. createDate 와 modifiedDate는 지속적으로 사용되는 변수여서 BaseEntity 로 선언한 뒤 상속을 받게 한다.
* 조회 및 검색이 불가하고 직접 생성해서 사용할 일이 없기 때문에 추상 클래스(abstract class)로 만드는 것이 좋다.
*/
/**
* @EntityListeners(AuditingEntityListener.class) : Spring Data JPA 에서 지원해주는 기능으로 생성일,수정일과 같은 기록들을 편리하게 관리할 수 있도록 지원해준다.
* Audit 기능 : spring data jpa 에서 시간에 대한 정보들을 자동으로 넣어주는 기능
* @CreatedDate : Entity가 생성되어 저장될 때 시간이 자동 저장
* @LastModifiedDate : 조회한 Entity의 값을 변경할 때 시간이 자동 저장
*/
@CreatedDate
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime modifiedDate;
}
또한, @EntityListeners(AuditingEntityListener.class)
어노테이션을 사용해서 Auditing 기능을 활성화 시켜주었습니다.
이 Auditing 기능을 인식하기 위해서 ---Application 에 @EnableJpaAuditing
어노테이션을 정의해주어야 합니다.
/**
* @EnableJpaAuditing : JPA Auditing 기능을 활성화 시켜주기 위해 적용
*/
@EnableJpaAuditing
@SpringBootApplication
public class EunstargramApplication {
public static void main(String[] args) {
SpringApplication.run(EunstargramApplication.class, args);
}
}
참고 링크 : https://wildeveloperetrain.tistory.com/76
(위 링크를 꼭 확인해주시고 공부!!!)
그럼 이런 상태에서 api 를 테스트 하기 위해 테스트 코드를 짰습니다. Controller layer 를 테스트 하려고 합니다.
@WebMvcTest(MemberController.class)
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private MemberService memberService;
@MockBean
private MemberJpaRepository memberJpaRepository;
private static final String COMMON_URL="/api/member";
@Test
@DisplayName("/signUp 요청시 200 status code 리턴")
void signUpTest() throws Exception {
//expected
mockMvc.perform(MockMvcRequestBuilders.post(COMMON_URL + "/signUp")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"memberId\" : \"testId\"," +
"\"password\" : \"1234\"," +
"\"nickName\" : \"Rabbit96\"," +
"\"phoneNumber\" : \"010-1111-2222\"," +
"\"birthDay\" : \"20220107\"," +
"\"intro\" : \"AA\"," +
"\"imagePath\" : \"location/1234\"," +
"\"cancelYN\" : \"N\"}")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
assertThat(memberJpaRepository.count()).isEqualTo(1);
}
}
이 테스트를 실행하면 잘 될까요????
안타깝게도 제목에 적은 에러가 발생합니다. 왜 이런 에러가 발생할까요?
---Application 에 정의한 @EnableJpaAuditing
와 Test Code 에 정의한 @WebMvcTest
어노테이션 때문입니다.@EnableJpaAuditing
어노테이션은 JPA 에 관한 Bean입니다.
그러나 @WebMvcTest
는 JPA 관련 Bean 들을 로드하지 않습니다.
(@WebMvcTest
는 대표적으로 @Controller
, @ControllerAdvice
어노테이션을 Bean 으로 로드합니다)
그래서 작성한 Test Code 에서 빈을 로드할 수 없기 때문에 JPA metamodel must not be empty! 에러가 발생하는 것이죠.
그럼 어떻게 해결할 수 있을까요??
해결방법 링크 : https://jeongkyun-it.tistory.com/199
(@WebMvcTest
를 유지한체로 해결하는 방법은 첨부해드린 링크를 참고하면 될 것 같습니다.)
전 슬라이스 테스트를 통합 테스트로 한번 변경해 보았습니다.
즉, @WebMvcTest
를 @SpringBootTest
변경하였습니다.
//@WebMvcTest(MemberController.class)
@SpringBootTest
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
//@MockBean
@Autowired
private MemberService memberService;
//@MockBean
@Autowired
private MemberJpaRepository memberJpaRepository;
private static final String COMMON_URL="/api/member";
@Test
@DisplayName("/signUp 요청시 200 status code 리턴")
void signUpTest() throws Exception {
//expected
mockMvc.perform(MockMvcRequestBuilders.post(COMMON_URL + "/signUp")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"memberId\" : \"testId\"," +
"\"password\" : \"1234\"," +
"\"nickName\" : \"Rabbit96\"," +
"\"phoneNumber\" : \"010-1111-2222\"," +
"\"birthDay\" : \"20220107\"," +
"\"intro\" : \"AA\"," +
"\"imagePath\" : \"location/1234\"," +
"\"cancelYN\" : \"N\"}")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
assertThat(memberJpaRepository.count()).isEqualTo(1);
}
}
@SpringBootTest
를 붙여줬습니다. 자!!이제 테스트를 실행해보려고 했더니....????
Could not autowire. No beans of 'MockMvc' type found.
이런 에러가 발생합니다. MockMvc 객체를 주입받지 못하는 상황인거죠. 한번 @WebMvcTest
를 들어가 볼까요?
@AutoConfigureMockMvc
어노테이션을 붙여주면 됩니다!!!
(@WebMvcTest
와 @AutoConfigureMockMvc
의 차이점이 무엇인지 공부!!)
//@WebMvcTest(MemberController.class)
@AutoConfigureMockMvc
@SpringBootTest
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
//@MockBean
@Autowired
private MemberService memberService;
//@MockBean
@Autowired
private MemberJpaRepository memberJpaRepository;
private static final String COMMON_URL="/api/member";
@Test
@DisplayName("/signUp 요청시 200 status code 리턴")
void signUpTest() throws Exception {
//expected
mockMvc.perform(MockMvcRequestBuilders.post(COMMON_URL + "/signUp")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"memberId\" : \"testId\"," +
"\"password\" : \"1234\"," +
"\"nickName\" : \"Rabbit96\"," +
"\"phoneNumber\" : \"010-1111-2222\"," +
"\"birthDay\" : \"20220107\"," +
"\"intro\" : \"AA\"," +
"\"imagePath\" : \"location/1234\"," +
"\"cancelYN\" : \"N\"}")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
assertThat(memberJpaRepository.count()).isEqualTo(1);
}
}
오늘의 일지 끝!!!
'나의 개발 메모장' 카테고리의 다른 글
@Transactional 은 mySql 의 auto_increment 값을 롤백시켜주지 않는다고요?! (0) | 2023.03.11 |
---|---|
[Javascript, Spring]fetch API 로 데이터 서버로 전송하기 (0) | 2023.02.21 |
[JUnit] controller 테스트시 java.lang.IllegalStateException: Failed to load ApplicationContext 에러 (0) | 2023.01.13 |
2022년 회고록 (6) | 2023.01.08 |
[Oracle] DBeaver 에서는 프로시저를 어떻게 실행시킬까? (0) | 2022.11.29 |