@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을 사용하여 주입
반응형

+ Recent posts