티스토리 뷰

728x90

스프링부트에서 테스트 코드를 작성할 때 자주 사용하는 @Mock@MockBean의 차이점. 이 두 어노테이션은 모킹(Mocking)을 통해 테스트를 효율적으로 작성할 수 있게 해주지만, 용도와 환경이 다르다. 또한, 리포지토리, 서비스 레이어, 컨트롤러 테스트 시 어떤 상황에서 어떤 어노테이션을 사용하는 것이 좋을지 작성.

@Mock

@Mock은 Mockito 프레임워크에서 제공하는 어노테이션이다. 특정 클래스의 모킹된 객체를 생성하며, 이 객체는 스프링 컨텍스트와는 무관하게 독립적으로 동작한다.

@MockBean

@MockBean은 스프링 부트에서 제공하는 어노테이션이다. 스프링 애플리케이션 컨텍스트에 모킹된 빈을 추가하고, 실제 스프링 빈 대신 모킹된 빈을 주입한다. 주로 통합 테스트 환경에서 사용된다.

@Mock 사용 예제

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    public void testGetUser() {
        User mockUser = new User("John", "Doe");
        when(userRepository.findByName("John")).thenReturn(mockUser);

        User user = userService.getUser("John");

        assertEquals("Doe", user.getLastName());
    }
}

@MockBean 사용 예제

@SpringBootTest
public class UserServiceTest {

    @MockBean
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @Test
    public void testGetUser() {
        User mockUser = new User("John", "Doe");
        when(userRepository.findByName("John")).thenReturn(mockUser);

        User user = userService.getUser("John");

        assertEquals("Doe", user.getLastName());
    }
}

차이점

  1. @Mock:
    • Mockito 라이브러리에서 제공.
    • 독립적인 모킹 객체를 생성.
    • 스프링 컨텍스트와 무관.
  2. @MockBean:
    • 스프링 부트에서 제공.
    • 스프링 애플리케이션 컨텍스트에 모킹된 빈을 등록.
    • 통합 테스트 환경에서 사용.

위의 예제를 통해 @Mock은 독립적으로 동작하고, @MockBean은 스프링 컨텍스트 내에서 모킹된 빈을 주입하는 차이를 알 수 있다.

리포지토리 테스트

리포지토리 테스트는 주로 데이터베이스와의 상호작용을 검증하는 테스트이다. 이때는 실제 데이터베이스와의 상호작용을 테스트하기 때문에 모킹이 필요하지 않다. 대신, 테스트 전용 데이터베이스를 사용하거나 @DataJpaTest를 사용한다.

@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void testFindByName() {
        User user = new User("John", "Doe");
        userRepository.save(user);

        User foundUser = userRepository.findByName("John");

        assertEquals("Doe", foundUser.getLastName());
    }
}

서비스 레이어 테스트

서비스 레이어 테스트는 비즈니스 로직을 검증하는 테스트이다. 이때는 의존하는 리포지토리나 다른 서비스들을 모킹하여 테스트한다. 여기서는 @Mock@InjectMocks를 사용해 단위 테스트를 작성한다.

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    public void testGetUser() {
        User mockUser = new User("John", "Doe");
        when(userRepository.findByName("John")).thenReturn(mockUser);

        User user = userService.getUser("John");

        assertEquals("Doe", user.getLastName());
    }
}

컨트롤러 테스트

컨트롤러 테스트는 주로 HTTP 요청과 응답을 검증하는 테스트이다. 여기서는 실제 서비스 레이어와의 상호작용을 모킹하여 테스트를 진행한다. 이때는 @MockBean을 사용해 서비스 빈을 모킹하고, @SpringBootTest 또는 @WebMvcTest를 사용해 통합 테스트를 진행한다.

@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void testGetUser() throws Exception {
        User mockUser = new User("John", "Doe");
        when(userService.getUser("John")).thenReturn(mockUser);

        mockMvc.perform(get("/users/John"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.lastName").value("Doe"));
    }
}

언제 어떤 것을 사용하는 것이 좋은가?

  1. 리포지토리 테스트: 실제 데이터베이스와의 상호작용을 검증하므로 모킹을 사용하지 않고, @DataJpaTest를 사용한다.
  2. 서비스 레이어 테스트: 비즈니스 로직을 검증하며, 의존하는 리포지토리나 다른 서비스를 모킹하기 위해 @Mock@InjectMocks를 사용한다.
  3. 컨트롤러 테스트: HTTP 요청과 응답을 검증하며, 서비스 레이어를 모킹하기 위해 @MockBean을 사용하고, @WebMvcTest를 사용한다.

이와 같이, 테스트 대상과 상황에 따라 적절한 모킹 기법과 어노테이션을 선택하여 효율적으로 테스트를 작성할 수 있다.

@Mock과 @MockBean 요약

  • @Mock: Mockito 라이브러리에서 제공하며, 독립적인 모킹 객체를 생성한다. 단위 테스트에서 주로 사용된다.
  • @MockBean: 스프링 부트에서 제공하며, 스프링 애플리케이션 컨텍스트에 모킹된 빈을 추가한다. 통합 테스트에서 주로 사용된다.

결론

  • @Mock은 단위 테스트에서 독립적인 객체 모킹에 적합.
  • @MockBean은 통합 테스트에서 스프링 컨텍스트에 모킹된 빈을 주입하는 데 적합.

참고

chatGTP4

 

https://onulmansanda.tistory.com/229

 

@Mock과 @MockBean의 차이는 뭘까?

자바 스프링부트로 테스트 코드를 짜던 중 Mock 어노테이션과 MockBean어노테이션이 있어 어떤 것을 이용해야하나 고민을 하다 둘의 차이가 궁금해졌다. @Mock 과 mock(*.class) 그리고 Mock어노테이션과

onulmansanda.tistory.com

https://cobbybb.tistory.com/16

 

Mockito @Mock @MockBean @Spy @SpyBean 차이점

예제 코드 https://github.com/cobiyu/MockitoSample Test Double이 왜 필요한 지부터 시작하는 기본적인 테스트 코드부터 한 단계씩 발전시켜나가며 Mockito의 어노테이션들의 정확한 쓰임새에 대해 살펴보겠습

cobbybb.tistory.com

https://simgee.tistory.com/58

 

mock() vs @Mock vs @MockBean 이제 그만 헷갈리자!

테스트를 수행하다보면, 실제 객체를 대신해주는 테스트용 객체를 생성해 줄 때, mock을 사용하게 됩니다. 이때마다 사용했던 mock() 과 @Mock 그리고 @MockBean 세가지에 대해 정리해보겠습니다. Mockito

simgee.tistory.com

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함