늦었지만~ 새해 복 많이 받으세요 ^^


오늘 포스팅은 JPA 와 Testing 에 관한 것 입니다.



최근들어 JPA가 많이 사용되는 것 같습니다~ 제가 속한곳의 프로젝트도 JPA로 작성하고 있구요~


그래서~ 오늘은 JPA 로 구현된 코드를 어떻게 테스트 할 것인지에 대한 내용을 포스팅 하려고 합니다.


이전 포스팅에서도 예고했듯이 오늘의 핵심은 바로 MockMvc & Transaction Testing 입니다.


먼저 일반적인 시나리오를 하나 볼까요?? (사용자 로그인 시나리오)

1. 사용자가 이메일 + 비밀번호를 입력하여 로그인 합니다.

2. 사용자의 정보가 DB에 존재한다면 정상 응답을 받을것이고 (2xx ok)

3. 사용자의 정보가 DB에 존재하지 않는다면 비정상 응답을 받을 것 입니다.(4xx client error) - e.g 가입되지 않은 사용자입니다 등등.. 


굉장히 심플하고 실제로 운영코드에도 사용되는 지극히 정상적인 시나리오 입니다 ㅎㅎ



 경우의 수 에 대한 생각을 한번 해볼게요~

1. 요청 정보가 제대로 되지 않은경우(일부 파라미터가 누락되었다거나... 요청방식이 잘못되었다거나....)

2. 사용자의 정보가 DB에 존재 및 존재하지 않는경우.

3. 기타 등등 


뭐 딱히 복잡한게 없습니다... 에러처리할 것도 별로 없고요~ 다음으로 넘어가볼까요?



기존 테스트 방식은 어떨까요?? 

글세요 이것은 사람마다 너무 달라서.... 제 방식으로만 설명드리자면... 크게 2가지 일텐데


- 로직검증 > 모듈검증 > 실제 환경을 수행하는 메소드나 클래스 단위로 검증

- 요청검증 > 실제로 요청 하여 DB 값 또는 반환값으로 검증


로직검증같은 경우에는 Mockito 를 많이 써서 임의의 값을 받고 넘겨주는 작업을 했으며(예를 들어서 MockHttpServletRequest, MockHttpSession 등등...)


요청검증의 경우에는 실제로 요청을 해보고 DB값을 갖고와서 Assert 에서 비교를 하거나, 반환값들을 Assert 에서 비교를 하곤 했지요~



오늘 여기서 다룰 것은~ 바로 2번째 요청검증에 대한 내용입니다.



먼저, 앞서 설명했던 사용자 로그인 시나리오를 볼까요??


일단 사용자로부터 이메일 + 비밀번호를 받아야 겠네요~


두번째로... DB에 사용자 정보가 있는지 없는지를 검증하구요!! 


마지막으로 반환값을 검증해야 합니다. 


근데!! 여기서 문제가 하나 있습니다... 로컬에서 테스트하고... 개발서버에서도 테스트하고.. 문제 없는데 만약에...


실제 운영서버에서 테스트하려면?? 

>> 임의의 사용자를 DB에 넣 그 사용자가 있는경우가 없는경우를 테스트 해야되나요?? DB에 더미값이 쌓이게 됩니다.



즉, 핵심은 이겁니다!! DB에 테스트 전 임시 사용자 값을 넣고 테스트가 종료되면 자동적으로 롤백되도록 하는거죠~



테스트 코드부터 보시죠


# Test Case 1. 회원이 존재하지 않는경우


@Test         public void test_user_not_exist() throws Exception {     // parameter     String email = "test@test.com";     // request get     mockMvc.perform( get("/user/login") .param("email", email)                 .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andDo(print()) .andExpect(status().is5xxServerError()) .andExpect(jsonPath("$.message").value("user is not exist")); }


------------------------------------------------------------------------------------------------------------------------------------------------------


# Test Case 2. 회원이 존재하는경우


	@Test
	public void test_user_exist() throws Exception {
		// parameter
		String email = "user@test.com";
		
		// insert user
		User user = new User();
		user.setType(User.USER_TYPE.USER);
		
		UserInfo userInfo = new UserInfo();
		userInfo.setEmail(email);
		userInfo.setUser(user);
		
		user.setUserInfo(userInfo);
		
                // persist
		userRepository.save(user);
		
		// request get
		mockMvc.perform(
				get("/user/login")
				.param("email", email)
				.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
					.andDo(print())
					.andExpect(status().is2xxSuccessful())
					.andExpect(jsonPath("$.message").value("user exist"));
	}



두번째 케이스만 보시면 될 것 같습니다~


파라미터는 패스워드를 임의로 누락시킨거니 신경쓰지 마시구요 ㅎㅎ 


중요한건 Insert user 부분입니다~ 실제로 DB에 JPA 를 이용하여 사용자 정보를 입력합니다. 


그리고 나서?? Controller 를 호출하는거죠~ 


마지막으로 Assert 작업을 합니다. 2xx OK 가 되었는지~ 결과값은 정상적인지요 


테스트가 끝나면?  아래와 같이 롤백됩니다~ 걱정하지 마세요 ^^



실제 바로 테스트 할 수 있는 코드를 Github에 올려놓았습니다.


테스트 해보시고~ 실제 작업에도 연동시켜 보세요~ 깔끔한 테스트 코드가 탄생할 지도 모르자나요? ~



https://github.com/okihouse/spring-jpa-test











+ Recent posts