JAVA/TEST

[JUnit5] assertEquals, assertAll, assertTimeout....

gracelove91 2020. 8. 13. 06:05

본 포스팅은 백기선님의 "더 자바, 애플리케이션을 테스트하는 다양한 방법" 을 보고 정리한 글 입니다.
관심 있으신 분들은 https://www.inflearn.com/course/the-java-application-test 를 살펴보세요

개요

테스트 자동화를 위한 Assertions 를 알아보자.

assertEquals

  • 이름에서 알 수 있다시피 기대하는 값과 실제 값이 동일한 지 검사하는 메서드다.

      static void assertEquals(Object expected, Object actual) {
          assertEquals(expected, actual, (String) null);
      }
    
      static void assertEquals(Object expected, Object actual, String message) {
          if (!objectsAreEqual(expected, actual)) {
              failNotEqual(expected, actual, message);
          }
      }
    
      static void assertEquals(Object expected, Object actual, Supplier<String> messageSupplier) {
          if (!objectsAreEqual(expected, actual)) {
              failNotEqual(expected, actual, messageSupplier);
          }
      }

사용법

    @Test
    void assert_test() {
        Study study = new Study(-10, 0);
        assertEquals(StudyStatus.DRAFT, study.getStatus(), "처음 스터디를 만들면 상태값은" + StudyStatus.DRAFT + "여야 한다.");
        assertEquals(StudyStatus.DRAFT, study.getStatus(), () -> "처음 스터디를 만들면 상태값은" + StudyStatus.DRAFT + "여야 한다.");
        assertEquals(StudyStatus.DRAFT, study.getStatus(), new Supplier<String>() {
            @Override
            public String get() {
                return "처음 스터디를 만들면 상태값은" + StudyStatus.DRAFT + "여야 한다.";
            }
        });
    }
  • 첫 번째 인수
    • expected. 기대하는 값을 넣어준다.
  • 두 번째 인수
    • actual. 실제 값을 넣어준다.
  • 세 번째 인수
    • message. 실패했을 때 콘솔에 기록되는 message를 넣어준다.

세 번째 인수에 String 이나 Supplier을 넣어줄 수 있다.
차이점은 String을 넣는다면 테스트가 실패하든 성공하든 매번 메시지를 생성하지만, Supplier는 실패할 때만 메시지를 생성한다.
조그마한 성능차이에도 불안하다면 Supplier를 사용하자.


assertThrows

  • 예상하는 익셉션이 발생하는 지 확인한다.

      public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable) {
          return AssertThrows.assertThrows(expectedType, executable);
      }

사용법

    @Test
    void assert_throws() {
        IllegalArgumentException illegalArgumentException =
                assertThrows(IllegalArgumentException.class, () -> new Study(10, -1));
        String message = illegalArgumentException.getMessage();
        assertEquals("최소 참석인원은 0 보다 커야 합니다.", message);
    }
  • 첫 번째 인수
    • Class expectedType. 발생하는 예외의 클래스를 넣어준다.
  • 두 번째 인수
    • Executable. 실제 행동을 넣어준다. 위 코드에서는 new Study(..) 를 했을 때 IllegalArgumentException이 발생하기를 기대한다.

assertAll

    public static void assertAll(Executable... executables) throws MultipleFailuresError {
        AssertAll.assertAll(executables);
    }
  • 원래 assertions 는 assertion 실패하면 그 밑의 코드는 더 이상 진행하지 않는다.
  • 만약 실패하더라도 다른 assertions 의 결과를 보고 싶다면 assertAll을 쓰자.

사용법

    @Test
    void assert_all() {
        Study study = new Study(-10, 0);
        assertAll(
                () -> assertNotNull(study),
                () -> assertEquals(StudyStatus.DRAFT, study.getStatus(),
                        () -> "스터디를 처음 만들면 " + StudyStatus.DRAFT + "상태 여야 합니다."),
                () -> assertTrue(study.getLimit() > 0, "스터디 최대 참석 가능 인원은 0보다 커야 합니다.")
        );
    }
  • assertAll 안에 있는 모든 assertion을 확인한다.

assertTimeout

/**
     * <em>Assert</em> that execution of the supplied {@code executable}
     * completes before the given {@code timeout} is exceeded.
     *
     * <p>Note: the {@code executable} will be executed in the same thread as that
     * of the calling code. Consequently, execution of the {@code executable} will
     * not be preemptively aborted if the timeout is exceeded.
     *
     * @see #assertTimeout(Duration, Executable, String)
     * @see #assertTimeout(Duration, Executable, Supplier)
     * @see #assertTimeout(Duration, ThrowingSupplier)
     * @see #assertTimeout(Duration, ThrowingSupplier, String)
     * @see #assertTimeout(Duration, ThrowingSupplier, Supplier)
     * @see #assertTimeoutPreemptively(Duration, Executable)
     */
    public static void assertTimeout(Duration timeout, Executable executable) {
        AssertTimeout.assertTimeout(timeout, executable);
    }
  • 지정한 시간 내에 assertion 실행이 완료되지 않는다면 테스트가 실패한다.

사용법

    @Test
    void assert_timeout() {
        assertTimeout(Duration.ofMillis(100), () -> {
            new Study(10, 10);
            Thread.sleep(300);
        });
    }
  • 100 밀리세컨드 이내에 Executable 코드가 실행완료 되어야 한다.
  • 주의할 점은 100 밀리세컨드가 지나자마자 테스트가 실패하는 게 아니라, Executable 코드가 모두 완료된 후에야 테스트 성공/실패를 결정짓는다.

깃헙 링크

링크