자바칩

[Spring] @MockBean 본문

Study/Spring

[Spring] @MockBean

아기제이 2024. 7. 19. 03:28
728x90

@MockBean은 Spring의 테스트 컨텍스트에서 목(mock) 객체를 정의하기 위해 사용됩니다. @MockBean을 사용하면 Spring의 애플리케이션 컨텍스트에 목 객체를 등록하여, 해당 목 객체를 실제 애플리케이션 빈 대신 사용하게 할 수 있습니다. 이는 주로 통합 테스트 또는 웹 계층 테스트에서 사용됩니다.

@MockBean의 역할

  • 목적: Spring 애플리케이션 컨텍스트에 목 객체를 등록하여, 해당 목 객체를 테스트에서 사용하도록 합니다.
  • 사용 위치: 주로 Spring의 컨트롤러, 서비스, 리포지토리 등을 테스트할 때, 해당 객체의 의존성을 목 객체로 대체하기 위해 사용됩니다.
  • 기능: @MockBean으로 정의된 객체는 Spring 컨텍스트에서 실제 빈 대신 사용되며, 이로 인해 실제 데이터베이스나 외부 시스템과의 상호작용을 목(mock)으로 대체할 수 있습니다.

@MockBean을 사용하는 이유

@WebMvcTest는 컨트롤러와 관련된 빈만 로드합니다. 이때, 컨트롤러가 의존하는 서비스나 리포지토리가 있다면, 이를 목 객체로 대체하여 테스트할 수 있어야 합니다. @MockBean을 사용하면, 컨트롤러가 의존하는 서비스나 리포지토리를 목 객체로 주입할 수 있습니다.

예시: UserControllerTest에서 @MockBean 사용

 
    @WebMvcTest(UserController.class)
    public class UserControllerTest {

        @Autowired
        private MockMvc mockMvc;

        @MockBean
        private UserService userService;

        @Test
        public void testCreateUser() throws Exception {
            UserDto userDto = new UserDto();
            userDto.setUsername("newUser");
            userDto.setPassword1("password");
            userDto.setPassword2("password");

            when(userService.createUser(any(UserDto.class))).thenReturn(1L);

            mockMvc.perform(post("/users")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(new ObjectMapper().writeValueAsString(userDto)))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.id").value(1L));

            verify(userService, times(1)).createUser(any(UserDto.class));
        }
    }
 

요약

  • @MockBean:
    • Spring 애플리케이션 컨텍스트에 목 객체를 등록합니다.
    • 주로 컨트롤러 테스트에서 컨트롤러가 의존하는 서비스나 리포지토리를 목 객체로 대체합니다.
    • Spring 컨텍스트가 로드될 때, 실제 빈 대신 목 객체를 사용하도록 합니다.

차이점 요약

  • @Mock:
    • 순수한 단위 테스트에서 Mockito를 사용해 목 객체를 생성.
    • Spring 컨텍스트와는 무관하게 목 객체를 생성하고 주입.
  • @MockBean:
    • Spring 컨텍스트에 목 객체를 등록하여 사용.
    • Spring 테스트 환경에서 컨트롤러나 서비스가 의존하는 빈을 목 객체로 대체.

이와 같은 이유로, @WebMvcTest를 사용하는 테스트에서는 컨트롤러가 의존하는 빈을 목 객체로 대체하기 위해 @MockBean을 사용합니다. 이는 테스트 대상 컨트롤러가 실제 환경과 유사하게 동작하면서도, 의존성에 대해 목 객체를 사용하여 테스트를 수행할 수 있게 합니다.


 

@Mock, @InjectMocks, @MockBean 처럼 왜 이름이 비슷한 어노테이션들을 따로 사용하는지 궁금해서 찾아보았다.

@McokBean은 스프링 컨텍스트에 목 객체를 등록하고, 컨트롤러가 의존하는 서비스나 레포지토리를 목 객체로 주입한다고 한다.

그러나 @Mock은 스프링 컨텍스트와는 무관하게 목 객체를 생성해서 주입하고, 순수 단위 테스트에서 Mockito를 사용해 목 객체를 생성한다고 한다.