스프링 부트에서 테스트 코드 작성

박지운·2023년 2월 13일
0

'스프링 부트와 AWS로 혼자 구현하는 웹 서비스'를 읽고 공부하며 정리한 내용입니다. 오류 해결부분은 틀린 내용이 있을 수 있습니다.😂

TDD

TDD는 테스트가 주도하는 개발을 뜻하고 테스트 코드를 작성하는 것부터 시작한다.

단위 테스트 코드

  1. 빠른 피드백이 가능
  2. 자동검증(사람이 더이상 눈으로 검증하지 않음)
  3. 개발자가 만든 기능을 안전하게 보호

테스트 코드는 새로운 기능이 추가될 때 기존 기능이 잘 작동되는 것을 보장해준다.
➡ 100% 익혀야하는 기술이자 습관

대중적인 프레임워크는 xUnit이 있고 자바용으로는 JUnit을 사용한다.


Hello Controller 테스트 코드 작성

@RunWith(SpringRunner.class)
@WebMvcTest
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;// 웹 api테스트, 스프링 mvc테스트의 시작점 ,get/post사용가능

    public void hello가_리턴된다() throws Exception {
        String hello = "hello";

        mvc.perform(get("/hello")) // MockMvc를 통해 get요청, 체이닝 지원 여러검증기능 이어서 선언가능
                .andExpect(status().isOk()) // perform의 결과 검증, Header의 status 검증
                .andExpect(content().string(hello));// 응답본문의 내용 검증 컨트롤러에서 hello를 리턴하기 떄문에 값 일치하는지 확인
    }
}

어노테이션 정리

@RunWith(SpringRunner.class) //스프링 부트 테스트와 JUnit 사이 연결
@WebMvcTest(controllers = HelloController.class) //여러 어노테이션중 Web에 집중
@Autowired /// 스프링이 관리하는 빈 주입받음


롬복 사용하기

자바 개발자들의 필수 라이브러리

롬복은 개발할 때 자주 사용하는 Getter, Setter, 기본 생성자, toString등을 어노테이션으로 자동 생성해준다.

에러 해결

org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method compile()...

compile, runtime, testCompile, testRuntime은 현재 내가 쓰고 있는 Gradle에서 쓰고 있지 않아 발생했다. 책에서 나온 compile을 implementation으로 수정하여 해결했다.

참고 : https://velog.io/@g0709-19/Gradle-Could-not-find-method-compile-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95/

롬복은 프로젝트마다 설정해야한다. 플러그인 설치는 한 번만 하면 되지만 build.gradle에 추가와 Enable annotation processing체크는 매번 해야한다.


Hello Controller 코드를 롬복으로 전환하기

큰 규모의 프로젝트라면 롬복전환이 힘들지만 테스트 코드가 있어 쉽게 변경이 가능하다.

public class HelloResponseDtoTest {
    
    @Test
    public void 롬복_기능_테스트() {
        
        String name = "test";
        int amount = 1000;
        
        HelloResponseDto dto = new HelloResponseDto(name, amount);
        
        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
        
    }
}
}

assertThat : assertj 테스트 검증 라이브러리의 메소드, 검증 대상을 인자로 받는다.

Junit에 비교한 assertj의 assertThat장점
1. 추가적인 라이브러리 필요하지 않음
2. 자동완성이 확실하게 지원됨

에러 해결

Lombok: variable not initialized in the default constructor

Gradle버전에 따라 롬복을 추가하는 방법이 바뀌어 발생했다.
의존성 주입 부분을 5.x 이상은

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

위 코드로 변경해야한다.

참고 : https://deeplify.dev/back-end/spring/lombok-required-args-constructor-initialize-error

어노테이션 정리

@Getter : 선언된 모든 필드의 get메소드를 생성
@RequiredArgsConstructor : 선언된 모든 final 필드가 포함된 생성자 생성
final이 없는 필드는 생성자가 생성되지 않음


HelloController에 ResponseDto 추가 후 테스트

@Test
  public void helloDto가_리턴된다() throws Exception {
      String name ="hello";
      int amount = 1000;

      mvc.perform(
              get("/hello/dto")
                  .param("name", name)
                  .param("amount", String.valueOf(amount)))
              .andExpect(status().isOk())
              .andExpect(jsonPath("$.name", is(name)))
              .andExpect(jsonPath("$.amount", is(amount)));

  }

param : api테스트 할 떄 사용될 요청 파라미터 설정, 값은 String만 허용
jsonPath : JSON 응답값을 필드별로 검증, $을 기준으로 필드명 명시

profile
앞길막막 전과생

0개의 댓글