java 진영의 대표적인 test Framework
단위 테스트를 위한 도구를 제공
TestEngine api 구현체로 Junit 5를 구현하고 있다.
테스트의 실제 구현체는 별도 모듈 역할을 수행하는데, 그 모듈 중 하나가 jupiter-engine 이다.
이 모듈은 jupiter-api를 사용하여 작성한 테스트 코드를 발견하고 실행하는 역할을 수행
개발자가 테스트 코드를 작성할 때사용된다.
Test를 실행하기 위한 뼈대
테스트를 발견하고 테스트 계획을 생성하는 TestEngine 인터페이스를 가지고 있다.
TestEngine을 통해 Test를 발견하고, 수행 및 결과를 보고함
그리고 각종 ide 연동을 보조하는 역할을수행
TestEngine api의 구현체로 junit3,4를 구현하고 있다
통합 테스트는 여러 기능을 조합하여 전체 비즈니스 로직이 제대로 동작하는지 확인하는 것을의미
통합테스트의 경우 @SpringbootTest를 사용하여 진행
단위테스트는 프로젝트에 필요한 모든 기능에 대한 테스트를 각각 진행하는 것을 의미
assertEquals(a,b) : 객체 a,b의 값이 일치하는 지 확인
assertArrayEquals(a,b) : 배열 a,b의 값이 일치하는지 확인
assertSame(a,b) : 객체 a, b 가 같은 객체인지를 확인 두 객체의 레퍼런스가 동일한지 확인
assertTrue(a) : 조건 a가 참인가를 확인
assertNotNull(a) : 객체 a가 null이 아님을 확인
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SpringBootTest
@ExtencWith
@WebMvcTest
@Autowired and
@Mockbean
@AutoConfigureMockMvc
@Import
필요한 클래스들을 Configuration으로 만들어 사용할 수 있다.
@DataJpaTest
@RestClientTest
@Json Test
컨트롤러를 테스트할때 기본적으로 해당 컨트롤러에서 주입받은 service를 사용하는것은 테스트코드가 실제 의존성에 영향이 있기때문에 @MockBean 을 사용해서
해당 서비스의 구현체를 모킹한다.
@MockBean을 통해서 등록된 목객체가 특정 상황에서 해야하는행위를 정의하는 메소드 이다. nestjs에 spy나 jest.fn()같은 역할을 한다.
Ex)
//컨트롤러를 테스트할때 의존돼있는 서비스를 모킹해서 모킹된 함수를 호출하고, 그 호출파라미터값과 그 파라미터값에 대한 기댓값또한(return값)개발자가 정해줄 수 있다.
given(productService.getProduct("123")).willReturn(new ProductDto("1233","name",4000,4044));
// 호출하는 목함수의 리턴값은 실제 리턴값과 맞춰줘야한다.
// 이렇게 하면 실제로 db에서 가져오지않고 가짜로 값을 가져오는것이 되는것이다.
위와같이 단순하게 given, when, then 이 세가지 함수를 지원해주는 라이브러리이다.
new ObjectMapper().writeValueAsString(오브젝트);
예를 들어 AService를 테스트한다고 할때 실제 AService에서 등록하는 빈만 테스트에 등록하면 AService를 테스트 할 수 있게된다.
이렇게 필요한 빈만 띄어서 테스트를 작성하는것을 단위테스트라고 하는데 이는 필요한 빈만 등록하기때문에 빠르게 테스트를 돌려볼수 있다는 장점이있지만
실제 서버에서 서비스를할때 잘 작동할것이라는 보장은 할 수 없다 왜냐하면 분리해서 테스트했으니까 다른곳에서 영향을 미칠 수 있기때문이다.
그래서 전체가 잘 돌아가지는지에 대한 테스트는 통합테스트를 해야하는것이다.
@ExtendWith(MockitoExtension.class)로 스프링환경을 띄어준 후에,해단 단위테스트에서 di하는 객체들 메모리에 띄우면 된다.
하지만이때 di돼있는 진짜 객체를 띄우면 실제 환경에 의존되기때문에 실제 객체를 사용하지 않는다.
@InjectMocks 를 사용해서 해당 객체에 @Mock로 등록된 모든 객체를 주입받는다.
@DataJapTest를 사용하면 jpa 관련된 애들과 Repository를 메모리에 띄운다.
그리고 실제 db를 사용할것인지 가짜 db를사용할것인지에 대한 설정은
@AutoConfigureTestDatabase(replace=Replace.ANY) 를사용해서 가짜 디비로 테스트를 할 수 있고, NONE은 실제 db 로 테스트한다.
@Transactinal을 붙여준다.
그리고 테스트하는 레파지톨리를 @Autowired로 di를 한다.
@WebMvcTest로 필요한 객체만 메모리에 등록하고 MockMvc를 di한다. 그리고 해당 컨트롤러에서 di돼 있는 서비스나 다른 객체들을 가짜로
@MockBean으로 가짜 빈등록을 한다. 가짜객체는 빈껍때기이기때문에 다음과같이 생명력을 불어넣는다고 생각하면된다.
given으로 준비를하고
when으로 행동을 지정한다.(thenReturn())
그리고 mockMvc.perform(httpMethod("주소").contentType("MIME").content(body))
또한 ResultActions타입으로 mockMvc에대한 결과를 받을 수 있다.
then으로 검증한다.
@SpringbootTest를 하면 모든 빈이 메모리에 뜬다.(빈이많을수록 오래걸림.)
@SpringbootTest를 사용할때는 webEnvironment.MOCK 옵션을 사용하면 실제 톰켓을 올리는 것이아니라 다른 톰켓으로 테스트 하는것이고
webEnvironment.RANDOM_PORT는 실제 톰켓으로 테스트 하는것
그리고 mockMvc를 메모리에 띄어서 서버 요청에대한 테스트를 한다.이때 모키토를 di를 하려면 @AutoConfigureMockMvc 가 있어야하는데 WebMvcTest가 들고있다.
@Trancavtional을 사용해서 각각의 테스트함수가 종료될때마다 트랜젝션을 rollback해주는 어노테이션
통합테스트는 postman사용하듯이 하면돼서 간단하다.
MvcResult requestResult = resultAction.andReturn();
String result = getResponse().getContentAsString();