Skip to content

Java Test Code 작성을 위한 공부 기록입니다.

Notifications You must be signed in to change notification settings

yhlee002/JavaTest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java Test Code 작성법(JUnit5 기준)

Spring 2.2 이상 버전의 SpringBoot 프로젝트 생성시 기본적으로 JUnit5 의존성이 포함된다.

의존성 추가(SpringBoot-starter-test 의존성을 사용하지 않는 경우)

Maven

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.5.2</version>
    <scope>test</scope>
</dependency>

Gradle

// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'

Test Code 생성 방법(macOS Intellij 기준)

default shortcut 기준으로 command + N으로 constructor, getter/setter 등을 만들 수 있는데, 이 때 test class도 생성할 수 있다.

Test 실행 방법(macOS Intellij 기준)

ctrl + shift + R

  • 특정 메서드에 커서가 있는 채로 누를 경우 해당 테스트 메서드만 실행된다.
  • 특정 메서드에 커서가 존재하지 않는 경우 해당 테스트 클래스 전체가 실행된다.

Basic Annotation

  • @Test : 해당 메서드가 테스트 메서드임을 의미(main method가 아니어도 단독 실행이 가능하다.)
  • @Disabled : 해당 테스트를 호출되지 않게 한다. (클래스의 테스트 메서드를 모두 실행해도 해당 테스트 메서드는 실행되지 않는다.)
  • @BeforeAll : 모든 테스트 메서드가 호출되기 전에 호출된다.
  • @AfterAll : 모든 테스트 메서드가 호출된 후에 호출된다.
  • @BeforeEach : 모든 테스트 메서드가 호출될 때마다 앞서서 호출된다.
  • @AfterEach : 모든 테스트 메서드가 호출될 때마다 따라 호출된다.

테스트명 표시하기

1. @DisplayNameGeneration annotation 사용

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class AppTest {
    @Test
    void create_new_app() {
        App app = new App();
        assertNotNull(app);
    }
}

위의 경우에는 해당 테스트명이 create new app으로 표시되게 된다.

인자로 제공되는 Name Generate 방식 - 기본 구현체로 제공하는 형태
  • ReplaceUnderscores : underscore(_)를 공백으로 치환한 이름을 만든다.
  • IndicativeSentences : 중첩된 클래스 또는 테스트 메서드로부터 지시문 생성(특정 문자열을 {0}과 같은 형태로 표시할 수 있다.)하여 이름을 만든다.
    • @Test 대신에 @ParameterizedTest@ValueSource을 같이 쓴다.
      @DisplayNameGeneration(DisplayNameGenerator.IndicativeSentences)
      class AppTest {
          @ParameterizedTest(name = "Name is {0}")
          @ValueSource(ints = {1, 2, 3})
          void testFunc() {
              // ...
          }
      }

2. DisplayName

  • @DisplayNameGeneration보다 우선순위가 높다.
  • 띄어쓰기나 한글, 이모지 등을 자유롭게 사용할 수 있다.

API

  • assertEquals() : 매개변수로 받은 두 인자가 같은지 확인한다.
  • assertTrue() : 매개변수로 받은 인자가 참인지 확인한다.
  • assertNull() : 매개변수로 받은 인자가 null인지 확인한다.
  • assertNotNull() : 매개변수로 받은 인자가 null이 아닌지 확인한다.
  • assertThrows() : 특정 타입의 Exceptionthrows되는지 확인한다.
    • 특정 타입의 Exception이 반환될 것으로 예상했는데 안되면 테스트에 실패한다.
    • 결과를 해당 타입의 Exception 객체로 반환받을 수 있다.
    class AppTest {
    
      @Test
      @DisplayName("assertThrows 작성")
      void checkThrows() {
          IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
                  () -> new App(-10));
          String message = exception.getMessage();
          assertEquals("limit은 0보다 커야 한다.", message);
      }
    }
  • assertTimeout() :
  • assertTimeoutPreemptively() :
    • ThreadLocal은 다른 스레드에 공유되지 않는다.
    • 🔥 Spring Transaction은 ThreadLocal을 기반으로 하기 때문에 종종 트랜잭션에 실패했는데도 Rollback되지 않는 문제가 발생하기도 한다. 주의하자.
  • assertAll() : Executable 타입을 인자로 받는다. 따라서 위의 api들을 람다식 형태로 변환해 이 메서드의 인자로 전달할 수 있다. 이러면 모든 테스트를 동시에 수행한다.
    class AppTest {
      @Test
      void create_app() {
          App app = new App();
          app.setStatus(AppStatus.DRAFT);
          app.setLimit(-10);
    
          /*
          assertNotNull(app);
          assertEquals(AppStatus.DRAFT, app.getStatus(),
                  () -> "스터디를 처음 만들면 상태값이 " + AppStatus.DRAFT + "여야 한다."); // 통과
          assertTrue(app.getLimit() > 0, "스터디 최대 참석 가능 인원은 0보다 커야 한다."); // 실패
           */
          
          // 위에 주석처리한 코드는 순서대로 테스트가 이루어졌다면, 테스트들을 모두 동시에 실행하는 메서드가 assertAll
          assertAll(
                  () -> assertNotNull(app),
                  () -> assertEquals(AppStatus.DRAFT, app.getStatus(),
                          () ->"스터디를 처음 만들면 상태값이 " + AppStatus.DRAFT + "여야 한다."),
                  () -> assertTrue(app.getLimit() > 0, "스터디 최대 참석 가능 인원은 0보다 커야 한다.")
          );
      }
    }
    • Cf. 실패 시 결과 : Multiple Failures (2 failures)

테스트 메세지 작성

테스트 실패시 콘솔에 해당 메세지가 출력되게 할 수 있다. 이 메세지를 람다식 형태로 전달해주면 필요할 때만 실행시키게 된다. (최소한으로 실행하여 리소스를 아낄 수 있다.)

  • Ex) assertEquals의 세 번째 인자로 메세지를 입력받아, 테스트 결과가 false일 경우 해당 메세지가 출력되게 할 수 있다.
class AppTest {
    @Test
    void check_equal() {
        App app = new App();
        app.setStatus(AppStatus.STARTED);
        assertEquals(AppStatus.DRAFT, app.getStatus(), () -> "스터디를 처음 만들면 상태값이 " + AppStatus.DRAFT + "여야 한다.");
    }
}

About

Java Test Code 작성을 위한 공부 기록입니다.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages