[JUnit5] assert 단언 메소드 사용시 메세지 출력 꿀팁!

대부분 assert 단언문을 사용할 때

@Test
public void test_1() {
	assertTrue(false, "false일 떄 메시지 출력");
}

assertTrue( boolean condition, String message); 

다음과 같이 assertXXX메소드에 인자 2가지를 전달하게 됩니다. 

 

이 중에서 결과는 true인데 message를 전달할 때, 여러가지 케이스가 복잡하게 존재하는 경우.. 과연 다음 테스트에 걸리는 시간이 얼마나 될까요..?

 

@Test
public void test_1() {
    long start = System.currentTimeMillis();
        assertTrue(true, getMessage());
        long end = System.currentTimeMillis();
        System.out.println("경과시간: "+ (end - start));
}

private String getMessage() {
  try {
    // 메시지를 결정하는 알고리즘.
    Thread.sleep(1000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  return "false일 떄 메시지 출력";
}

결과 : 경과시간: 1007

 

결과는 당연히 true 라서 메시지는 필요가 없는 상황이 되었습니다. 그런데 메시지를 결정하기 위한 로직이 1초나 소요됬는데 그걸 그대로 기다려야할 필요가 없지 않겠습니까??

 

@Test
    public void test_1() {
        long start = System.currentTimeMillis();
        assertTrue(true, () -> getMessage());
        long end = System.currentTimeMillis();
        System.out.println("경과시간: "+ (end - start));
    }

결과 : 경과시간: 3

 

결론부터 말씀드리자면 다음과 같이 람다식의 함수형 인터페이스를 이용한다면 됩니다. 그 이유가 무엇일까요???

 

JUnit5 내부 소스

내부 코드를 들여다보면 다음과 같이 오버로딩 된 코드가 보입니다. 그중에서 저희는 방금 5번째 메소드를 사용한 것입니다.(아래에서 2번째)

 

오버로딩된 메소드중 Supplier 타입의 인자가 보일 것입니다. 이는 보다 내부로 가면 어떻게 동작하는지 확연히 보입니다.

 

condition이 true일 경우 그냥 통과할 것이나 false일 경우 안의 로직을 통해 AssertionUtils.buildPrefix(AssertionUtils.nullSafeGet(messageSupplier)) 이 구문을 통해 메시지가 확정되어 지는데, 

 

저희는 AssertionUtils.nullSafeGet(messageSupplier) 이부분을 한번 더 들여다 보겠습니다. 우리가 보낸 인자가 아직 사용되지 않았기 때문입니다.

 

nullSafeGet 메소드 내부는 다음과 같습니다. messageSupplier 가 우리가 보낸 Supplier 람다식 함수형 인터페이스인데, .get() 메소드를 통해 안에있는 내부 메소드를 실행하게 됩니다. 그로인해 test_str() 함수가 실행될 것이고 스레드가 1초동안 정지했다가 문자열을 리턴하도록 하였죠.

 

이러한 부분은 처음에 assertTrue로 넘겼던 condition 조건의 true/false 결과에 따라 실행이 좌우됩니다. 즉 필요없으면 실행안되도록 하는 방법인 것입니다.

 

댓글

Designed by JB FACTORY