반응형
고민
- spring-boot-starter-test에 보면 @MockBean이 제공되고 있다. 기존에 Mockito의 @Mock과 무엇이 다른지 어느걸 쓰는게 boot관점에서 더 정확할지 고민되었다.
결론
- 상황에 맞게 쓰면된다.
- Spring에서 제공하는 applicationContext와 연계가 필요하면 @MockBean
- 로직확인용 Mock이 필요하다면 @Mock + @InjectMock
- 따라서 대게는 @Mock을 사용하고(이때 MockitoJUnitRunner로 Runwith한다) Spring에서 제공되는 WebMvcTest와 함께 사용될때는 @MockBean을 사용하면 된다.
접근방법
Spring에서 제공되는 MockBean을 이용한 단순한 테스트 코드이다.
someService를 MockBean으로 해준다.
재밌는점은 메소드 결과 주입도 spring에서 제공할거 같았는데 mockito에서 제공하는 given을 사용한다.
https://github.com/spring-projects/spring-boot/search?q=MockBean
혹시 몰라서 spring-boot프로젝트에서도 찾아봤는데 역시나 given을 쓰는걸 볼 수 있다.
@RunWith(SpringRunner.class) @WebMvcTest(SomeController.class) public class SomeControllerTest { @Autowired private MockMvc mvc; @MockBean private SomeService someService; @Test public void 테스트() throws Exception { given(someService.execute()).willReturn(mockResult()); mvc.perform(MockMvcRequestBuilders.get("/some/test")) .andExpect(MockMvcResultMatchers.status().isOk()) }
보통 간단한 유닛테스트일때는 MockitoJUnitRunner를 사용하는게 더 빠르다.
@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
@InjectMocks
private SomeService someService;
@Mock
private SomeRepository someRepository;
}
참고
spring-boot-starter-test의 의존성을 보면 기본적으로 org.mockito도 포함되는 걸 볼 수 있다. mockito에서 제공하는 given과 같은 메소드도 별도로 추가없이 사용가능하다.
\--- org.springframework.boot:spring-boot-starter-test -> 2.2.0.RELEASE +--- org.springframework.boot:spring-boot-starter:2.2.0.RELEASE (*) +--- org.springframework.boot:spring-boot-test:2.2.0.RELEASE | \--- org.springframework.boot:spring-boot:2.2.0.RELEASE (*) +--- org.springframework.boot:spring-boot-test-autoconfigure:2.2.0.RELEASE | +--- org.springframework.boot:spring-boot-test:2.2.0.RELEASE (*) | \--- org.springframework.boot:spring-boot-autoconfigure:2.2.0.RELEASE (*) +--- com.jayway.jsonpath:json-path:2.4.0 | +--- net.minidev:json-smart:2.3 | | \--- net.minidev:accessors-smart:1.2 | | \--- org.ow2.asm:asm:5.0.4 | \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.28 +--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.2 | \--- jakarta.activation:jakarta.activation-api:1.2.1 +--- org.junit.jupiter:junit-jupiter:5.5.2 | +--- org.junit.jupiter:junit-jupiter-api:5.5.2 | | +--- org.apiguardian:apiguardian-api:1.1.0 | | +--- org.opentest4j:opentest4j:1.2.0 | | \--- org.junit.platform:junit-platform-commons:1.5.2 | | \--- org.apiguardian:apiguardian-api:1.1.0 | +--- org.junit.jupiter:junit-jupiter-params:5.5.2 | | +--- org.apiguardian:apiguardian-api:1.1.0 | | \--- org.junit.jupiter:junit-jupiter-api:5.5.2 (*) | \--- org.junit.jupiter:junit-jupiter-engine:5.5.2 | +--- org.apiguardian:apiguardian-api:1.1.0 | +--- org.junit.platform:junit-platform-engine:1.5.2 | | +--- org.apiguardian:apiguardian-api:1.1.0 | | +--- org.opentest4j:opentest4j:1.2.0 | | \--- org.junit.platform:junit-platform-commons:1.5.2 (*) | \--- org.junit.jupiter:junit-jupiter-api:5.5.2 (*) +--- org.junit.vintage:junit-vintage-engine:5.5.2 | +--- org.apiguardian:apiguardian-api:1.1.0 | +--- org.junit.platform:junit-platform-engine:1.5.2 (*) | \--- junit:junit:4.12 +--- org.mockito:mockito-junit-jupiter:3.1.0 | +--- org.mockito:mockito-core:3.1.0 | | +--- net.bytebuddy:byte-buddy:1.9.10 -> 1.10.1 | | +--- net.bytebuddy:byte-buddy-agent:1.9.10 -> 1.10.1 | | \--- org.objenesis:objenesis:2.6 | \--- org.junit.jupiter:junit-jupiter-api:5.4.2 -> 5.5.2 (*) +--- org.assertj:assertj-core:3.13.2 +--- org.hamcrest:hamcrest:2.1 +--- org.mockito:mockito-core:3.1.0 (*) +--- org.skyscreamer:jsonassert:1.5.0 | \--- com.vaadin.external.google:android-json:0.0.20131108.vaadin1 +--- org.springframework:spring-core:5.2.0.RELEASE (*) +--- org.springframework:spring-test:5.2.0.RELEASE | \--- org.springframework:spring-core:5.2.0.RELEASE (*) \--- org.xmlunit:xmlunit-core:2.6.3
'일반적인 로직적용' 카테고리의 다른 글
.use(moment()에서 java LocalDateTime으로 변환하기) (0) | 2021.01.25 |
---|---|
.use(@Nullable의 재발견) (0) | 2020.12.21 |
.use(awaitility를 사용하여 딜레이 테스트하기) (0) | 2020.12.20 |
.use(@DataRedisTest) (0) | 2020.12.20 |
.use(jpa 조건절에서 and 속에서 or사용하기) (0) | 2020.12.20 |