똑같은 삽질은 2번 하지 말자

Spring Boot 개념다지기 No.8(테스트) 본문

Spring/Spring Boot

Spring Boot 개념다지기 No.8(테스트)

곽빵 2020. 4. 27. 23:30

음 테스트 코드를 짜던 도중 새로운 코드작성법? 을 하나 익혔는데

지금 SampleServices 라는 클래스가 없는 상황에서 하나하나 새로운 클래스 작성할 때 처럼

패키지 클릭하고 class 만드는 이름치고 만드는 작업을

그냥 F2하나로 줄여버릴수 있다.(저기 빨간줄에 커서대고 F2 누르면 아마 느끼실껍니다. 편안함을)

물론 저기 속하는 getName함수도 똑같이 적용 가능!

 

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) // Servlet인듯 아닌 Mock
@AutoConfigureMockMvc // interaction 을 위해 
public class SampleControllerTest {
	@Autowired
	MockMvc mockMvc;
	
	@Test
	public void hello() throws Exception {
		mockMvc.perform(get("/hello"))
				.andExpect(status().isOk())//200
				.andExpect(content().string("helloheewon"))
				.andDo(print());//출력
	}
}

이건 mock Servlet을 이용한 테스트코드다.

(/hello 라는 get 요청을 보내면 return "helloheewon" 하게 해둔 controller가 있다.)

import static 친구들을 조심하자 워낙 종류가 많아서 이상한거 써버리면 빨간줄 계속 끄인다.

 

결과창

 

 

이 결과창 안에 있는 내용들을 다 테스트 해 볼 수 있 다.(다음기회에..)

 

이번엔 다른 테스트 케이스

package com.example.gwak.sample;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.gwak.controller.SampleService;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleControllerTest {
	@Autowired
	TestRestTemplate testRestTemplate;
	@MockBean
	SampleService mockSampleService; // SampleService Mock을 만들어서
	@Test
	public void hello() throws Exception {
		when(mockSampleService.getName()).thenReturn("gwak");// 이렇게 하면 굳이 SampleService가 필요없다.
		
		String result = testRestTemplate.getForObject("/hello", String.class);
		assertThat(result).isEqualTo("hellogwak"); // helloheewon -> hellogwak으로 바뀌는걸 알수 있따.
	}
}

내장 톰캣을 구동하는 테스트 코드다 코드를 보면 RANDOM_PORT를 준 걸 알 수 있다.

그리고 Service단까지 끌어오는것 보다 Mock을 만들어서 해주면 편한쓰~하게 테스트가 가능하다.

 

이번엔 webclient라는 비동기인 친구로 테스트를 해보자.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

의존성 하게 추가하고

 

API 헷갈린다 주의하자..(정리하다가 코드가 날라가버려서 선생님 코드 스샷 대체)

 

지금까지 해온 테스트들은 다 통합테스트이다. (@SpringBootTest 어노테이션 자체가 통합테스트용)

그렇다면 레이어별로 잘라서 테스트 하고 싶을 때? @SpringBootTest 대신

레이어 별 테스트

  • @JsonTest -> 말그대로 Json테스트
  • @WebMvcTest -> Controller Service 만
  • @WebFluxTest
  • @DataJpaTest

 

엇? 스프링 부트 테스트 끝난줄 알았는데...

밑 목록은

테스트 유틸

  • OutputCapture -> 제일 많이 쓰이는 유틸 결과창 캡처하는 친구
  • TestPropertyValues
  • TestRestTemplate
  • ConfigFileApplicationContextInitializer

 

outputCapture 예

Comments