본문 바로가기
IT/자바

@Mock vs Mock() vs @MockBean

by 모띠 2025. 4. 19.
반응형

 

 

 

junit5로 테스트케이스를 만들다보면 늘 헷갈리던 어노테이션들이 있다.

 

일단, 전부 mock객체를 만드는 것은 확실한데.. 도대체 어느 시점에 @Mock을 써야하고 Mock()은 또 뭐고 각자의 기능은 동일한것인지에 관해 이번기회에 정리해보려고 한다.

 

@Mock vs Mock() vs @MockBean

 

Mockito.Mock()

클래스 or 인터페이스의 mock 객체를 생성

mock 객체를 사용해, 해당 객체가 가진 메서드의 반환값을 조작하거나 해당 메서드가 호출되었는지 확인가능

@Test
public void MockTest () {
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
//    UserRepository localMockRepository = mock(UserRepository.class);    
    Mockito.when(localMockRepository.count()).thenReturn(123L);

    long userCount = localMockRepository.count();

    Assert.assertEquals(123L, userCount);
    Mockito.verify(localMockRepository).count();
}

 

@Mock

Mockito.Mock()의 축약형 = 동일한 기능을 제공

Mock()과는 다르게 클래스에만 사용가능

Mock()과는 다르게 활성화 해야지만 사용가능. (2가지 방법)

  • @ExtendWith(MockitoExtension.class)
  • MockitoAnnotations.openMocks(this); 호출 / .initMock();
@ExtendWith(MockitoExtension.class)
public class MockAnnotationTest {
    
    @Mock
    UserRepository mockRepository;
    
//    @BeforeEach
//    void setUp() {
//        MockitoAnnotations.openMocks(this);
//    }    
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        long userCount = mockRepository.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

 

@MockBean

@MockBean은 @mock과 달리 org.springframwork.boot.test.mock.mockito 패키지에 존재한다.

즉, spring-boot-test에서 제공하므로 스프링부트에서만 사용가능하다.

해당 어노테이션이 선언된 객체는 빈이 되어 스프링이 관리하는 applicationContext.xml안으로 들어간다.

만약, 동일한 객체가 존재하면 MockBean으로 덮어씌운다.

@ExtendWith({ SpringExtension.class, MockitoExtension.class })
@ContextConfiguration(classes = BeanConfig.class)
public class MockBeanAnnotationTest {
    
    @MockBean
    UserRepository mockRepository;
    
    @Autowired
    ApplicationContext context;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        // 기존에 UserRepository객체가 있더라도 MockBean으로 인해 mock객체가 호출된다.
        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

 

@InjectMock

만약, 스프링부트가 아닌 스프링에서 @MockBean처럼 특정 빈을 모킹하고싶다면 @InjectMock을 사용하면된다.

@InjectMock은 mock으로 선언된 객체를 자동 주입한다. 나머지 객체는 null주입

@ExtendWith({ SpringExtension.class, MockitoExtension.class })
@ContextConfiguration(classes = BeanConfig.class)
class ServiceTest {

    @Mock
    UserRepository userRepository; 

    @InjectMocks // (@AutoWired X)
    UserService userService;  

    @Test
    void testGetUser() {
        User mockUser = new User("john", "password123");
        when(userRepository.findByName("john")).thenReturn(mockUser);

        User user = userService.getUserByName("john");

        assertThat(user).isEqualTo(mockUser); 
        Mockito.verify(userRepository).findByName("john");  
    }
}

 

반응형

댓글