[Spring] Testing Code - 슬라이스 테스트

·2022년 12월 14일
1

Spring

목록 보기
23/24
post-thumbnail
post-custom-banner

슬라이스 테스트(Slice Test)

Solo Project로 진행했던 TODO applicatin 기반으로 진행
깃허브 링크

단위 테스트의 경우에는 테스트를 진행하는 테스트 케이스(메서드)에 @Test 애너테이션을 추가한 것만으로도 원활한 진행이 가능했다.

그에 반해 슬라이스 테스트는 테스트를 진행하는 테스트 클래스 자체를 Application Context로 생성해야 한다.

API 계층

Controller 클래스 테스트를 진행할 때, 2가지 방법을 사용할 수 있다.
1. ✔️@SpringBootTest + @AutoConfigureMockMvc
2. @WebMvcTest(TodoController.class) + @ExtendWith(SpringExtension.class)

1번의 방법은 애플리케이션의 전체 구성을 로드하여 테스트 케이스를 실행한다. 보통 통합 테스트를 진행할 때 사용하는 애너테이션이다.

2번의 방법은 Controller 테스트 케이스를 진행할 때 사용하는 애너테이션으로 1번은 애플리케이션의 전체 구성을 로드하기 때문에 테스트 실행 속도가 비교적 느리다. 2번은 오직 Controller 테스트만을 위한 애너테이션이기 때문에 더 빠른 속도로 테스트 케이스를 진행할 수 있다.

🤔 그럼 2번 방법을 사용하면 되지 않나?
이 경우에는 Controller에서 사용하는 컴포넌트들을 하나하나 설정해줘야 하는 번거로움이 존재한다. Service, Mapper 객체만 생성해준다면 다행이지만 때에 따라 데이터 액세스 계층과의 의존성도 설정해주어야 한다!

Mockito

Mock : 거짓된, 가짜의 => 가짜!

Mockito는 Mocking 라이브러리

🤔 Mocking : 단위 테스트, 슬라이스 테스트 등에서 Mock(가짜) 객체를 사용하는 것

Mockito는 Mock 객체를 생성하고, 생성된 객체를 진짜처럼 동작할 수 있도록 도와주는 역할을 한다. 이 기능을 이용해 테스트하고자 하는 대상에서 다른 영역을 단절(슬라이스 테스트)시켜 테스트 대상에만 집중할 수 있도록 한다.

🧐예를 들어
Controller 클래스Service 클래스와 연동되어 있기 때문에 Controller의 기능만을 테스트하기에는 어려움이 있다. 이때 Mockito를 통해 Mock Service 객체를 생성하고 Mocking 하면 Controller의 기능만을 테스트할 수 있다.

@MockBean

: Application Context에 등록되어 있는 Bean에 대한 Mockito Mock 객체를 생성하고 주입해주는 역할을 한다.

Stubbing

: Mockito에서 지원하는 메서드로 테스트를 위해 Mock 객체가 항상 일정한 동작을 하도록 지정하는 것을 말한다.

No, Mockito

본격적인 비즈니스 로직을 구현하기 전, API 문서화를 위해 실행하는 테스트에서는 다른 계층과의 연동이 되어 있지 않은 상태이기 때문에 Mockito 없이 테스트 로직을 구현한다.

No, Mockito의 기본 테스트 케이스 구조

  • @SpringBootTest : Spring Boot 기반 애플리케이션의 테스트를 위해 Application Context로 생성
  • @AutoConfigureMockMvc : Controller 테스트를 위한 애플리케이션의 자동 구성 작업 진행 (MockMvc 기능을 사용하기 위해 반드시 추가해줘야 한다)

MockMvc : Spring MVC 테스트 프레임워크, 서버를 실행하지 않고 테스트할 수 있는 환경을 지원해준다.

  • @Autowired : 의존성 주입(DI)을 나타내는 애너테이션으로 타입으로 필요한 의존 객체의 타입에 해당하는 빈을 찾아 주입해준다. 필드 멤버, 생성자, Setter에 적용 가능하다.

Controller의 postMember() 메서드를 테스트하는 테스트 케이스

given

  1. Post Request body에 담긴 정보(MemberPostDto)를 테스트 케이스에 주어진다.
  2. MemberPostDto를 Gson 객체를 이용하여 역직렬화 한다.

🧐 Gson 라이브러리(디펜던시 추가 필요)
Json 변환 라이브러리로서 실제 로직에서는 Mapper를 이용하여 직렬화하지만, 테스팅 코드에서는 그 역할을 Gson이 대신한다.

when

  • ResultActions : Controller의 메서드를 실행한 결과값을 담는 객체, 검증을 위한 메서드를 사용할 수 있다.
  • mockMvc.perform() : MockMvc의 객체로 테스트할 동작을 수행한다.

then

  • MvcResult : 검증이 완료된 테스트의 결과값을 담는 인터페이스

Yes, Mockito

비즈니스 계층, 데이터 액세스 계층까지 구현하고 난 뒤, 테스트를 진행하려면 계층 간의 연동을 끊어야 한다. 이때는 Mockito를 이용하여 가짜객체를 생성해 테스트를 진행한다.

Business 계층

비즈니스 로직은 데이터 액세스 계층과는 무관하게 구현된 비즈니스 로직 자체를 Spring 프레임워크의 도움 없이 빠르게 테스트를 진행할 수 있어야 한다.
그렇다면 @SpringBootTest와 같은 애너테이션을 사용하지 않고 순순하게 Mockito만으로 테스트를 진행해야 한다.

  • @ExtendWith(MockitoExtension.class) : Mockito 기능을 사용할 수 있게 해준다.
  • @Mock : 해당 애너테이션이 추가된 필드는 Mock객체를 생성한다.
  • @InjectMocks : @Mock 애너테이션이 붙은 Mock객체를 주입할 수 있는 애너테이션

🧐 @Mock 애너테이션이 추가된 Mock TodoRepository객체는 TodoService에 DI된다.

Data Access 계층

데이터 액세스 계층을 테스트할 때, DB의 테스트 하기 전과 후의 상태를 유지하는 것을 가장 주의해야 한다.

테스트 케이스는 정해진 순서가 없어 테스트마다 결과값이 달라질 수 있는 것이다.

  • @DataJpaTest : JPA의 테스트를 진행해주는 애너테이션. 전체 자동 구성이 비활성화되고 오직 JPA 테스트와 관련된 configuration만 적용된다.

    @DataJpaTest@Transactional애너테이션을 가지고 있기 때문에 테스트 하나가 종료되면 자동으로 rollback이 이루어진다.
profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게
post-custom-banner

0개의 댓글