JUnit 4 테스트 작성 (2) - 단위테스트 구성과 MVC Test

gentledot·2021년 3월 28일
0

테스트와 로깅

목록 보기
3/5

개요

  • 테스트 환경에서 단위테스트를 구현하는 방식에 대해 정리하고자 포스트를 작성하였습니다.
  • 정보를 찾아 테스트를 작성하였지만 작성된 단위테스트에 대한 피드백을 받을 수 없는 환경이기 때문에 부정확한 정보가 정리되었을 수 있습니다.
  • 테스트 환경은 이전 포스트에 정리하였습니다.

    잘못된 내용이나 더 나은 방식 등에 대한 의견은 댓글로 피드백 부탁드리겠습니다. :)

테스트를 작성해보자!

정리할 내용!

  • MVC 기능 확인을 위한 Controller test
  • 비즈니스 로직 구현 확인을 위한 service (logic) test
  • 확인하고자 하는 단위 외의 영역은 stubbing 하기
  • unit test를 작성하며 refactoring 을 진행하기

보이스카우트 원칙 : (클린코드 p18-19)

  • 잘 짠 코드가 전부는 아니다. 시간이 지나도 언제나 깨끗하게 유지해야 한다.
    • 변수 이름을 하나씩 개선
    • 조금 긴 함수가 있다면 하나씩 분할
    • 중복인 부분은 통합, 불필요 라인 제거
    • 복잡한 if문 하나씩 정리

unit-test의 작성

  • build - operate - check 패턴*으로 테스트 구성

  • 구성 정리

    /------ arrange ------/
      String accountCode = "812000";
      AccountingVO accountingVO =  getTestAccountingVOForSearching(cd_account, "1"); // 검색조건 : 여비교통비, 집계구분 = 프로젝트
      
      /------ act ------/
      // 출력 데이터 조회
      List<AccountingVO> printIncomeExpensesAllList = (List<AccountingVO>) incomeExpensesService.selectIncomeListForPrint(accountingVO);
      
      /------ assert ------/
      assertThat(printIncomeExpensesAllList.size(), is(9)); // list의 조회 수는 9개로 설정됨 
      // 조회된 sq_code 확인 = 1자리 수 (ex) 1 = 총괄 (cd_ 인 경우에는 2자리수 : 01)
      assertThat(printIncomeExpensesAllList.get(0).getSq_code(), is(30L));
    • build : 테스트에 필요한 변수 설정

    • operate : 실제 테스트할 대상 로직

    • check : 로직결과나 로직에서 확인이 필요한 데이터에 대한 단언(assert). 예상된 값과 실제 생성 값의 비교

      *Arrange - Act - Assert (AAA)로도 표현 가능

  • 기타

    • 단위테스트의 작성은 테스트용도이기도 하지만 로직을 작은 단위로 뜯으며 확인하는 과정이기 때문에 해당 단위에 대한 기능 명세로써도 사용할 수 있다고 생각합니다. (대상 모듈의 기능명세서)
    • 테스트를 디버깅으로 돌리면서 바로 output을 확인할 수 있긴 하지만 그래도 필요한 주석은 달아두는 게 좋다고 생각합니다. (주석이 아예 없는 것보다야 주석이 과한게 그나마 낫다고 생각합니다.)
    • AAA 이던, given-when-then 이던 정해진 형식에 무조건 맞춰야 할 필요는 없다는 생각입니다. 우선은 테스트를 작성하고 알아보기 쉽게 정리하는 과정에서 자연스레 형식은 맞춰질 것입니다.

MVC Test

@ModelAttribute 대응

  • @ModelAttribute("ObjectVO") ObjectVO objectVO 가 controller의 param으로 설정된 경우 parameter로 전달되는 항목을 ObjectVO class와 대응하여 변환이 처리됩니다.

  • Spring 4.0.3 버전 상에서는 여러 개의 param을 설정할 구문이 없는 상태로 확인됩니다.

    • Spring framework 4.3+ 부터는 tring key, String value 형식의 MultiValueMapperform.params() 에 넣어 대응할 수 있다고 합니다.

    • 객체 값을 param으로 설정할 대안을 찾다가... get 요청 uri 문자열을 구성하여 설정하고자 하는 parameter를 추가하는 식으로 대응하였습니다.

      StringBuilder builder = new StringBuilder("/slip/getSlip.do?");
      paramMap.forEach((key, value) -> {
          if (value != null) {
              builder.append("")
                      .append(key)
                      .append("=")
                      .append(value)
                      .append("&");
          }
      });
      
      url = builder.toString();
      url = url.substring(0, (url.length() - 1));
      ResultActions perform = mockMvc.perform(post(url)
                  .session(mockSession));
      
      MvcResult mvcResult = perform.andDo(print())
                  .andExpect(jsonPath("success").value(true))
                  .andReturn();
      
      • url 문자열 구성은 StringBuilder를 사용하였습니다. (마지막 "&"은 제거하여 구성)
      • mockMvc로 request 테스트 요청 시 MockMvcRequestBuilders 의 get(), post()를 사용합니다.
      • mockMvc의 session은 MainTest에서 생성된 MockSession을 가져와 구성하였습니다.
    • print()를 통해 나오는 결과는 다음과 같이 출력됩니다.

      MockHttpServletRequest:
      	   HTTP Method = POST
      	   Request URI = /slip/getSlip.do
      	    Parameters = {mode=[0], testParam1=[0], testParam2=[2], ...}
      	       Headers = {}
      	
      	       Handler:
      	          Type = ...
      	        Method = ...
      
      ...

MockMvcResultMatchers.jsonPath 실행 오류

  • MockMvcResultMatchers.jsonPath 확인 시 아래의 예외 발생할 수 있습니다.

    java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException
  • 해당 예외가 발생되는 경우, jsonPath를 확인할 수 있도록 의존성을 추가하여아 합니다. (

    • com.jayway.jsonpath

    • 주의할 점은, 최신 버전을 바로 적용할 수 없고 테스트 버전간 호환성 확인이 필요하다는 점입니다.

      • 참고 : JsonPath와 Spring Test 간 버전 호환성

      • 최신 버전을 적용 시 다음의 예외가 발생됨을 확인하였습니다.

        // 2.4.0 버전으로 동작시 예외 발생
        java.lang.NoSuchMethodError: com.jayway.jsonpath.JsonPath.compile(Ljava/lang/String;[Lcom/jayway/jsonpath/Filter;)Lcom/jayway/jsonpath/JsonPath;
    • Spring 4.0.3의 테스트 환경에서는 0.9.x 버전을 적용하여야 정상 동작하는 것으로 확인됩니다.

      <dependency>
          <groupId>com.jayway.jsonpath</groupId>
          <artifactId>json-path</artifactId>
      		<version>0.9.1</version>
      </dependency>
profile
그동안 마신 커피와 개발 지식, 경험을 기록하는 공간

0개의 댓글