반응형

 

 

 

 

 

Mockito

 

 

➤ Mock이란?

 

mock의 사전적 의미

not real, but intended to be very similar to real situation, substance etc

 

테스트 할 때 Mock의 의미 : 가짜 객체

단위 테스트나 슬라이스 테스트 등에 Mock 객체를 사용하는 것을 Mocking이라고 한다.

 

 

 

➤ 테스트에서 Mock 객체를 사용하는 이유

 

 

▶️ Mock 객체를 사용하지 않고 테스트를 수행할 경우

 

테스트 하고자 하는 계층(클래스)가 다른 계층이나 데이터베이스까지 호출하기 때문에 슬라이스 테스트라고 보기 어렵다.

예를 들어 API 계층을 테스트하기 위해 Controller를 테스트할 때 Mock 객체가 없으면

Controller에 요청을 보내고 Controller는 Service 를 호출하고

Service는 다시 요청에 맞는 메서드를 데이터액세스 계층인 Repository에서 호출할 것이다.

그러면 Repository는 DB에서 해당하는 명령을 수행하고 다시 돌아간다.

이렇게 되면 Controller 뿐 아니라 모든 계층을 원치않게 다 테스트하게 된다.

이러면 테스트에 실패했을 때 어느 부분이 문제인지 제대로 파악하기 어렵다.

 

이런 문제 때문에 Mock 객체가 필요하다.

Mock 객체를 사용하면 Controller를 테스트할 때

Service 객체가 아닌 MockService 객체를 호출하여 더이상 다른 계층을 호출하는 것을 막아준다.

Mock 객체를 사용하면 다른 계층과 단절하여 불필요한 과정을 줄일 수 있게 된다.

 

 

 

➤ Mockito 란?

 

Mock 객체로 Mocking을 할 수 있게 해주는 다양한 오픈 소스 라이브러리가 있다.

Mockito는 그 중에 가장 많이 사용하고 Spring Framework 자체적으로 지원하고 있는 라이브러리이다.

 

Mockito의 Mocking 기능을 이용해서 테스트 하려는 대상 외의 다른 영역을 단절시켜 오로지 테스트 대상에만 집중할 수 있다.

 

 

 

➤ 슬라이스 테스트에 Mockito 적용

 

 

▶️ @MockBean

 

필드에 추가하면 Application Context에 등록되어 있는 Bean에 대한 Mockito Mock 객체를 생성하고 주입(DI)해주는 역할을 한다.

 

 

▶️ Stubbing 메서드

 

Mockito에서 지원하는 메서드 이다.

 

✅ given()

Mock 객체가 특정 값을 리턴하는 동작을 지정하는데 사용한다.

Mockito에서 지원하는 when()과 동일한 기능을 한다.

Mickito.any() 에 매개변수로 실제로 리턴받을 타입을 지정해준다.

 

※ void 타입으로 리턴시에는 doNothing()으로 한번 감싸준다.

ex) doNothing().when(orderService).deleteOrder(anyLong());

 

 

✅ willReturn()

메서드가 리턴할 Stub 데이터이다.

 

 

▶️ Stubbing 이란?

 

테스트를 위해서 Mock 객체가 항상 일정한 동작을 하도록 지정하는 것을 의미한다.

 

 

▶️ @ExtendWith(MockitoExtension.class)

 

Spring을 사용하지 않고, Junit에서 Mockito의 기능을 사용하기위해 test 클래스 이름 위에 추가해준다.

 

 

▶️ @Mock

 

필드에 추가하면 해당 필드의 객체를 Mock 객체로 생성한다.

 

 

▶️ @InjectMocks

 

필드에 추가하면 생성한 Mock 객체를 주입해준다.

 

 

 

 

TDD

 

 

➤ TDD(Test Driven Development) 란?

 

테스트 주도 개발

테스트가 중심으로 하는 개발을 말한다.

테스트 부분을 먼저 만들고 코드 구현은 그 다음에 한다.

 

 

➤ TDD 가 아닌 전통적인 개발 방식

 

TDD 방식이 아닌 방식으로 개발하면 일반적으로 코드를 먼저 작성해서 구현한 후에 테스트를 통해 문제가 있는지 확인한다.

선 구현, 후 테스트

 

 

➤ TDD 방식으로 개발하기

 

메서드 작성 전에 먼저 테스트 클래스 부터 만든다.

존재하지 않는 클래스로 에러가 떠도 일단 테스트를 작성한다.

 

테스트 클래스가 passed 하는 방향으로 코드를 작성한다.

(처음에 클래스가 없어서 나오는 에러도 실행하면 passed 하지 않기 때문에 “failed” 라고 볼 수 있다.)

 

모든 조건에 만족하는 테스트를 먼저 작성 ➡️ 조건에 만족하지 않는 테스트 작성

단계적으로 작성하면서 해결한다.

 

실패하는 테스트 ➡️ 실패하는 테스트를 성공할 만큼의 기능 구현 ➡️ 성공하는 테스트 ➡️ 리팩토링 ➡️ 실패하는 테스트와 성공하는 테스트 확인

 

TDD 개발 방식 모식도

 

 

 

➤ TDD의 장점과 단점

 

 

▶️ 장점

 

  • 테스트를 통과할 만큼만 기능을 구현해서 한번에 너무 많은 기능을 구현할 필요가 없다.
  • 테스트 코드가 추가되면서 검증 범위가 넓어질 수록 기능 구현도 점진적으로 완성된다.
  • 리팩토링 할 부분이 보이면 그때그때 빠르게 진행하기 때문에 리팩토링의 비용이 상대적으로 작아진다.
  • 이미 잘 동작하는 코드를 수정하는 일은 부담스럽지만 TDD 방식은 항상 테스트 케이스가 존재하기 때문에 기존의 코드를 수정해도 상대적으로 심리적 불안감이 줄어든다.
  • 리팩토링을 통해 꾸준히 코드를 개선해서 코드의 품질을 일정 부분 유지할 수 있다.
  • 코드 수정 이후 바로 테스트를 진행할 수 있어서 수정 결과를 빠르게 피드백 받을 수 있다.

 

 

▶️ 단점

 

  • 테스트를 먼저 작성하는 것이 익숙하지 않다.
  • 팀 단위 개발에서 팀원들 간 사전에 협의가 되어야 한다.

 

 

 

 

 

 

감사합니다.

오개념에 대한 지적은 늘 환영입니다. 🤩

 

 

반응형