Business Layer & mock
userService가 userRepository에 의존하고 있기 때문에,
userService의 테스트코드 실행 시 실제 DB와의 연동
이 불가피함
=> userRepository를 가짜객체로 만들기
=> DB와의 연동이 일어나지 않아 효율적!
유저목록 조회 단위테스트
@Mock // userRepository는 가짜 객체가 됨
private UserRepository userRepository;
@InjectMocks // userService가 의존하는 Mock 객체인 userRepository를 주입(DI)받음
private UserService userService;
@Test
void getUsers() throws Exception {
// given
List<User> users = getUserList();
// when : userRepository는 빈껍데기인 가짜객체이기 때문에 아무런 기능을 하지 않음 따라서 특정 메서드 호출에 대한 반환값 명시필요
doReturn(users).when(userRepository).findAll();
// then : userService.findUsers() 메서드는 userRepository.findAll() 메서드가 호출된 반환값을 반환, 그렇기 때문에 users가 위에서 명시한 것처럼 users 가 반환됨
List<User> userList = userService.findUsers();
assertThat(userList.size(), is(users.size())); // 사이즈가 같음을 확인
}
MockMVC
API의 경우 함수실행을 위해 메소드가 아닌 API가 호출됨
-> API요청을 받아 전달
하기 위한 별도객체 필요
-> Spring Test에서는 이를 위해 MockMVC 지원
- MockMVC : 애플리케이션을 서버에 배포하지 않고도 Spring 의 MVC test 가능하게 해줌
Controller에 대한 API를 받아 넘겨줄 수 있음
MockMVC 설정
- @ContextHierychy : 테스트용 DI container 작성 시 Bean파일 저장
@ContextHierarchy({
@ContextConfiguration(classes = AppConfig.class),
@ContextConfiguration(classes = WebMvcConfig.class)
})
- @WebAppConfiguration : Controller 및 web환경에 사용되는 빈을 자동으로 생성하여 등록
MockMVC 실행 : perform()
- perform() + 요청설정 메소드 : 요청에 대한 설정
- perform() + Expect 메소드 : 테스트 진행
@Test
public void testController() throws Exception{
mockMvc.perform(
get("test"))
.param("query", "부대찌개")
.cooke("쿠키 값")
.header("헤더 값:)
.contentType(MediaType.APPLICATION.JSON)
.content("json으로")
.andExpect(status().isOk()) // 여기부터 검증
.andExpect(content().string("expect json값"))
.andExpect(view().string("뷰이름"));
.andDo(print()) //여기부터 기타 메소드
.andDo(log());
status 검증 -> content 검증 -> view 검증
1개라도 통과하지 않으면 테스트는 fail
MockMVC 요청설정 메소드
param
,params
: 쿼리스트링 설정cookie
: 쿠키설정requestAttr
: 요청 스코프객체 설정sessionAttr
: 세션 스코프객체 설정content
: 요청본문 설정header
,headers
: 요청헤더 설정contentType
: 본문타입 설정
검증 메소드
status
: 상태코드 검증header
: 응답 header 검증content
: 응답본문 검증cookie
: 쿠키상태 검증view
: 컨트롤러가 반환한 뷰이름 검증redirectedUrl(Pattern)
: 리다이렉트 대상의 경로 검증model
: 스프링 MVC 모델 상태 검증request
: 세션스코프, 비동기 처리, 요청스코프 상태 검증forwardedUrl
: 이동대상의 경로 검증
기타 메소드
andDo()
: print, log 사용할 수 있는 메소드- print() : 실행결과 출력
- log() : 실행결과를 디버깅 레벨로 출력
MockMVC로 Controller API Test
@Autowired
private MockMvc mockMvc;
@Test
class ControllerTest{
@Autowired
private MockMvc mockMvc; // mockMvc 생성
@Test
public void testController() throws Exception{
String jjson = "{\"name\": \"부대찌개\"}";
//mockMvc에게 컨트롤러에 대한 정보를 입력
mockMvc.perform(
get("test?query=food") //해당 url로 요청
.contentType(MediaType.APPLICATION_JSON) // Json 타입으로 지정
.content(jjson) // jjson으로 내용 등록
.andExpect(status().isOk()) // 응답 status를 ok로 테스트
.andDo(print()); // 응답값 print
)
}
}
- MockMVC 생성하기
- MockMVC에게 요청에 대한 정보 입력하기
- 요청에 대한 응답값을 Expect를 이용하여 테스트
- Expect가 모두 통과하면 테스트통과
- Expect가 1개라도 실패하면 테스트 실패
지난번 예시보다 쉬운 예시
둘 다 해보기!
Reference
https://ronick-grammer.github.io/spring/Spring-Mock-%ED%85%8C%EC%8A%A4%ED%8A%B8/
https://itmore.tistory.com/entry/MockMvc-%EC%83%81%EC%84%B8%EC%84%A4%EB%AA%85
https://goodteacher.tistory.com/257