@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ExtendWith(MockitoExtension.class)
@SpringBootTest
public class SampleServiceTest {
@Autowired
private MasterService masterService;
@Mock
private SlaveService slaveService;
@Test
void test() throws IOException {
when(slaveService.checkPrint(any())).thenReturn(null);
masterService.path(null);
}
}
@SpringBootTest는 스프링 컨텍스트를 로드하면서 실제 빈을 주입한다. 때문에 SlaveService는 @Mock으로 선언되어있지만 실제 MasterService는 스프링컨테스트에서 실제빈을 주입받아 처리하기에 SlaveService의 Mock객체가 MasterService에 주입되지 않고, 실제 빈이 사용된다.
해결 방법으로는 크게 두가지 이다.
1. @InjectMocks 사용
@InjectMocks를 사용하면 @Mock으로 사용한 선언된 객체들이 MasterService에 자동으로 주입된다.
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ExtendWith(MockitoExtension.class)
@SpringBootTest
public class SampleServiceTest {
@InjectMocks
private MasterService masterService; // mock 객체가 주입됨
@Mock
private SlaveService slaveService;
@Test
void test() throws IOException {
when(slaveService.checkPrint(any())).thenReturn(null);
masterService.path(null);
}
}
2. @MockBean 사용
@MockBean을 사용하면 SpringBootTest가 실행될 때 slaveService의 실제 빈 대신 Mock객체가 주입된다.
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ExtendWith(MockitoExtension.class)
@SpringBootTest
public class SampleServiceTest {
@Autowired
private MasterService masterService;
@MockBean
private SlaveService slaveService;
@Test
void test() throws IOException {
when(slaveService.checkPrint(any())).thenReturn(null);
masterService.path(null);
}
}
차이점 요약
주입방식 | MasterService 객체 | SlaveService 객체 |
@InjectMocks + @Mock | 실제 객체 (테스트용으로 생성) | Mock 객체 |
@Autowired + @MockBean | 스프링 빈 (실제 빈) | Mock 객체 (스프링 컨텍스트 내에서 등록됨) |
따라서,
- 단위 테스트를 할 때는 @InjectMocks를 사용하여 빠르게 테스트
- 스프링 컨텍스트와 함께 통합 테스트를 할 때는 @MockBean을 사용하여 주입
반응형