brunch

You can make anything
by writing

C.S.Lewis

by 백명석 Oct 23. 2015

spring-boot integration test삽질

spring-boot라면 이러지 말았어야 ^^

@IntegrationTest를 이용한 spring-boot integration test시 request body에 해당하는 POJO에 default constructor가 없으면 테스트 대상 메소드가 아예 호출이 안된다. 오류 메시지도 없이...

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=0" })
public class ArticleControllerIntegrationTest {
    @Value("${local.server.port}")
    private int port;
    private RestTemplate template;

    @Before
    public void setUp() throws Exception {
        template = new TestRestTemplate();
    }

    @Test
    public void write_article() {
        final String writeArticleUri = "http://localhost:" + port + "/articles";
        WriteArticleRequest requestModel = new WriteArticleRequest("title01", "content01");

        WriteArticleViewModel viewModel = template.postForObject(writeArticleUri, requestModel, WriteArticleViewModel.class);

        assertThat(viewModel.id, is(notNullValue()));
        assertThat(viewModel.title, equalTo(requestModel.title));
        assertThat(viewModel.content, equalTo(requestModel.content));
    }
}

위의 테스트 코드는 아래의 controller 메소드를 호출하기를 기대했다.

@RestController
public class ArticleController {
   @Autowired
   private WriteArticleInteractor interactor;

   @Autowired
   private WriteArticlePresenter presenter;

   @RequestMapping(value = "/articles", method = RequestMethod.POST)
   public WriteArticleViewModel writeArticle(@RequestBody WriteArticleRequest request) {
      assert presenter != null;
      assert interactor != null;
      validate(request);
      WriteArticleResponse response = interactor.interact(request);
      WriteArticleViewModel viewModel = presenter.present(response);
      viewModel.id = "1";
      return viewModel;
   }
   ...
}

그런데 @RequestBody로 지정한 WriteArticleRequest는 아래와 같이 default constructor가 없었다.

public class WriteArticleRequest implements RequestModel {
   public String title;
   public String content;

   public WriteArticleRequest(String title, String content) {
      this.title = title;
      this.content = content;
   }
}

이 경우 위의 ArticleController#writeArticle 메소드가 호출되지 않았다. 한참을 헤매다가 혹시 하는 마음에 WriteArticleRequest에 default constructor를 추가하였더니 그제야 제대로 호출이 되었다.

아마 문서를 잘 살펴보면 @RequestBody로 사용할 객체는 POJO Bean 규약을 준수해야 한다는 내용이 있었을지도 모르겠다. 하지만 spring-boot라면 이와 같은 경우 적절한 오류 메시지를 뿌려주었어야지  않나???

라는 생각이 강력하게 든다.


ps 위 코드는 Robert C Martin이 OOP 2015에서 언급한 Clean Architecture를 프로토타이핑하는 과정에서 작성하였다.

작가의 이전글 다음카페 개발자를 모십니다
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari