반응형
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");
}
}
반응형
'IT > 자바' 카테고리의 다른 글
Junit in Action 3판 - 8장) 모의 객체로 테스트하기 (0) | 2025.04.19 |
---|---|
Junit in Action 3판 - 7장) 스텁을 활용한 거친 테스트 (0) | 2025.03.24 |
Junit in Action 3판 - 6장) 테스트 품질 (0) | 2025.03.15 |
Junit in Action 3판 - 5장) 소프트웨어 테스트 원칙 (0) | 2025.03.15 |
Junit in Action 3판 - 4장) Junit4에서 Junit5로 전환하기 (0) | 2025.03.15 |
댓글