Programming/Spring

[스프링부트 (8)] SpringBoot Test(1) - Junit 설정 및 실행

byeong07 2022. 5. 29. 22:46

[스프링부트 (8)] SpringBoot Test(1) - Junit 설정 및 실행

 

이번 포스팅은 [ 스프링 부트  테스트 시작하기 (Junit 테스트 방법)입니다. : ) 

 

 

 

 

0. 들어가기 앞서

사실 Junit을 포스팅 한다기 보다는 Spring Boot에서 제공하는 테스트 기능을 사용하기 앞서 한번 끊어가는 시간이라고 보면 될 것 같다.

궁극적으로는 스프링 부트에서 제공하는 기능으로 통합테스트, 단위테스트 방법을 정리 하려고  한다.

이에 앞서 기본적으로 사용되는 Junit의 설정 및 IntelliJ에서 Junit 테스트 방법에 대해 간단히 정리 하려고 한다.

 

1. Junit 설정

▶ 1. Junit 이란? 특징?

 - Java에서 독립된 단위테스트(Unit Test)를 지원해주는 프레임워크이다.

 - 단정(assert) 메서드로 테스트 케이스의 수행 결과를 판별한다.(ex: assertEquals(예상값, 실제값))
 - jUnit4 이후부터는 테스트를 지원 어노테이션을 제공한다.(@Test @Before @After 등)
 - @Test 메서드가 호출할 때 마다 새로운 인스턴스를 생성하여 독립적인 테스트가 이루어지게 한다.

 

▶ 2. Junit 환경 설정

 - IntelliJ + SpringBoot 기반으로 테스트 하였다.

 - 사실 스프링 이니셜라이져로 프로젝트를 생성한 경우 Dependency에서부터 거의 설정을 따로 해줄 것이 없는데 그건 "spring-boot-starter-test" 때문이다.

 

1) 스프링부트 테스트 디펜던시

 - 스프링부트는 애플리케이션 테스트를 위한 많은 기능을 두 가지 모듈로 제공한다.

   ① spring-boot-test : 핵심 기능 포함
   ② spring-boot-test-configuration : 테스트를 위한 AutoConfiguration 제공

 - 이니셜 라이즈로 프로젝트를 생성 하였으면 이미 테스트를 위한 디펜던시가 추가 되어 있다.

   ("spring-boot-starter-test")

 

2) "spring-boot-starter-test" 에는 다음 라이브러리들이 포함되어 있다.

 - JUnit 5 (JUnit 4와의 하위 호환성을위한 빈티지 엔진 포함)

   (이에 별다른 설정 없이 Junit5도 사용 가능)
 - 스프링 테스트 및 스프링 부트 테스트
 - AssertJ
 - Hamcrest
 - Mockito
 - JSONassert
 - JsonPath

 

※ 스프링 부트 2.x 이후버전에서는 JUnit 4 및 JUnit 5 테스트를 모두 실행할 수 있다.

JUnit 5로 마이그레이션 한 경우 다음 예제와 같이 JUnit 4 지원을 제외해야 하는데, 스프링 이니셜라이져로 프로젝트를 생성한 경우 이미 제외 되어 있을 것이다.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
  	</exclusion>
  </exclusions>
</dependency>

▶ 3. IntelliJ 에서 Junit 테스트

3.1 프로젝트 구조 설정

 - 이미 만들어져 계신분도 있겠지만, 테스트할 클래스의 패키지를 설정 해주자.

 

① 테스트 폴더 생성

 - 프로젝트 하위 test 폴더가 없는 경우 test Directory 생성

 

 

 

② 테스트 클래스 선정 및 프로젝트 구조

 - 나와 같은 경우는 JPA 또는 MVC 패턴에서 사용되는 DTO(Vo, Domain)을 테스트 해보려 한다.

 - 이에따라 다음과 같이 Vo 클래스를 생성하였고, test 폴더 하위에도 똑같이 구조를 잡았다.

 

 

※ JUnit테스트는 테스트 대상 클래스와 테스트 클래스는 같은 패키지 내에 있어야 한다. 이를 고려하여 위와 같이 설정 하였으니 참고 하자.

 

③ 모듈 설정

 - 위 이미지에서 test > java 폴더만 초록색으로 설정되어 있는데 다음과 같이 설정하면 된다.

 - File > Project Structure > Module' 로 가서 해당 디렉토리 선택 후 Mark as에서 'Tests'를 선택하고 적용한다.

 - Test Source Folders로 지정이 되면 아래와 같이 초록색 폴더로 바뀐다.

 

 

 

④ 기존 Class 및 Test Class 소스

1) 기존 Vo

package com.god.bo.jpaTest.vo;

import lombok.*;
import javax.persistence.*;

@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name="member")
public class MemberVo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long mbrNo;

    private String id;

    private String name;

    @Builder
    public MemberVo(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

 

2) Test Class 생성

 - 클래스에 커서를 두고 Alt + Enter 키를 누르고 Create Test를 누른다.

 

 

 

 - Testing Library 선택(Junit5, Junit4도 물론 선택 가능하다.)

 

 

 

※ 테스트 코드 작성

 - 다음과 같이 정말 정상 동작을 확인할 수 있는 수준의 테스트 코드를 작성하였다.

package com.god.bo.jpaTest.vo;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MemberVoTest {

    @Test
    public void getId(){
        final MemberVo memberVo = MemberVo.builder()
                .id("goddaehee")
                .name("갓대희")
                .build();
        final String id = memberVo.getId();
        assertEquals("goddaehee", id);
    }
}

1) 테스트 클래스는 반드시 public으로 선언해야 한다.

2) 클래스명은 관례상 테스트클래명 + Test 끝나는 이름으로 사용 한다.

3) @Test 어노테이션을 선언한 메서드는 JUnit이 알아서 실행 할 수 있게 한다.

 

 

3.2 테스트 코드 실행

1) 테스트를 원하는 메서드 실행

 

 

 - "Test passed" : 정상 처리 된 것을 볼 수 있다.

 

 

 

2) 오류 테스트 메서드

 - 다음 소스를 추가 하자.

package com.god.bo.jpaTest.vo;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MemberVoTest {

    @Test
    public void getId(){
        final MemberVo memberVo = MemberVo.builder()
                .id("goddaehee")
                .name("갓대희")
                .build();
        final String id = memberVo.getId();
        assertEquals("goddaehee", id);
    }

    @Test
    public void getName(){
        final MemberVo memberVo = MemberVo.builder()
                .id("goddaehee")
                .name("갓대희")
                .build();
        final String name = memberVo.getName();
        assertEquals("대희", name);
    }
}

 

 - getName() 실행 해보자.

 - vo에 담긴 이름과 기대하는 이름이 틀리기 때문에 오류가 발생한다.

 

 

 

3) 해당 클래스의 전체 메서드 테스트

 - 해당 클래스 우클릭 하여 전체 메서드를 테스트 해본다.

 

 

 

 - 테스트 가능한 메서드가 모두 실행되었고, 어던 프로세스가 실패, 성공하였는지 확인 가능하다. 

 

 

 

※ 참고 

assertEquals(a, b); 객체 A와 B의 실제 값이 일치한지 확인한다.
assertSame(a, b); 객체 A와 B가 같은 객체임을 확인한다.
 - assertEquals 메서드는 두 객체의 값의 비교
 - assertSame 메서드는 두 객체가 동일한지 객체의 비교 (== 연산자와 같다)
assertTrue(a); 조건 A가 참인가를 확인한다.
assertNotNull(a); 객체 A가 null이 아님을 확인한다.

 - 이외 JUnit assert 메서드에 대하여  더 자세한 내용은 jUnit JavaDoc을 확인해보자.

  (http://junit.sourceforge.net/javadoc/org/junit/Assert.html)

 

다음 포스팅에서부터 @SpringBootTest, @WebMvcTest, @DataJpaTest, @DataMongoTest 등 스프링 부트에서 제공하는 기능을 통하여 통합테스트, 단위테스트를 진행 해볼 예정이다.