Controller 테스트에서 생성자 주입을 잘 사용하지 않는 이유는?

Ssol·2023년 10월 26일
0

JUnit5에서는 @WebMvcTest 내에 @ExtendWith를 통해 @Autowired를 인지해서 생성자 주입을 할 수 있게 되었다.

@Import(SecurityConfig.class)
@WebMvcTest(ArticleController.class)
class ArticleControllerTest {

    private final MockMvc mvc;

    // 일반적인 스펙상 생성자 주입을 할 때 생성자 위에 붙여주는 @Autowired는 생략이 가능하다.
    ArticleControllerTest(@Autowired MockMvc mvc) {  // 하지만 테스트 패키지에 있는 생성자 주입은 파라미터에 꼭 @Autowired를 붙여야 한다.
        this.mvc = mvc;
    }

		...

}

그런데 많은 컨트롤러 테스트 코드에서 왜 이 생성자 주입 방식을 잘 사용하지 않을까?

생성자 주입에 사용되는 @Autowired의 문서를 확인해보면

Autowired

메서드와 파라미터에도 사용이 가능해서 생성자 주입에 사용해도 전혀 문제가 없지만

보통 컨트롤러라 함은 서비스를 의존성으로 가지고 있다. 그래서 테스트 시 이 의존성을 끊어주고 mocking을 해주는 @MockBean을 사용하게 되는데 이 어노테이션의 문서를 확인해보면

MockBean

사용할 수 있는 곳이 타입과 필드 뿐이다. 메서드, 파라미터에 넣을 수가 없는 것이다. 그래서 생성자 주입에 @MockBean를 사용할 수가 없다.

그렇게 되면 결국

@Import(SecurityConfig.class)
@WebMvcTest(ArticleController.class)
class ArticleControllerTest {

    private final MockMvc mvc;

    @MockBean  // @WebMvcTest의 컨트롤러 단에 의존하는 의존성 테스트를 위해 사용. 컨트롤러에 있는 의존성을 끊고 mocking 해준다.
    private ArticleService articleService;

    // 일반적인 스펙상 생성자 주입을 할 때 생성자 위에 붙여주는 @Autowired는 생략이 가능하다.
    ArticleControllerTest(@Autowired MockMvc mvc) {  // 하지만 테스트 패키지에 있는 생성자 주입은 파라미터에 꼭 @Autowired를 붙여야 한다.
        this.mvc = mvc;
    }

		...

}

이렇게 생성자 주입과 필드 주입이 동시에 사용될 수 밖에 없다는 말인데 이러면 통일성이 없는 혼종 코드가 되버리기 때문에

@Import(SecurityConfig.class)
@WebMvcTest(ArticleController.class)
class ArticleControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean  // @WebMvcTest의 컨트롤러 단에 의존하는 의존성 테스트를 위해 사용. 컨트롤러에 있는 의존성을 끊고 mocking 해준다.
    private ArticleService articleService;

		...

}

그냥 필드 주입으로 통일시켜 MockMvc도 필드 주입으로 많이 사용하는 것이다.

예전 IntelliJ에서는 필드 주입 방식을 사용하면 주황색으로 필드 주입은 권장하지 않는다는 경고 표시를 했지만 지금 버전의 IntelliJ는 테스트 코드에 한해선 필드 주입을 해도 경고 표시를 띄우지 않는다.

profile
Junior Back-end Developer 🫠

0개의 댓글