[JUnit] 단언(assert) 파보기


junit 단언에 대해 파보자.

1. Junit 단언이란?

단언은 어떤 조건이 참인지 검증하는 방법. 보통 요즘은 햄크레스트 단언을 많이 사용한다.

1-1. assertTrue

가장 기본적인 단언. 특정 조건이 참인지 검증

   @Test
   public void depositIncreasesBalance() {
      int initialBalance = account.getBalance();
      account.deposit(100);
      assertTrue(account.getBalance() > initialBalance);
      assertThat(account.getBalance(), equalTo(100));
   }

1-2 assertThat

명확한 값을 비교하는 단언. 햄크레스트 단언의 일종.

   @Test
   public void depositIncreasesBalance_hamcrestAssertTrue() {
      account.deposit(50);
      assertThat(account.getBalance() > 0, is(true));
   }

햄크레스트 단언에는 두번째 인자로 matcher를 넣을 수 있음.

   @Test
   public void assertFailure() {
      assertThat(account.getName(), startsWith("xyz"));
   }

matcher를 인자로 넣은 상태에서 테스트가 실패하면 아래와 같은 stacktrace가 나와서 문제 해결에 필요한 정보를 쉽게 알 수 있음.

java.lang.AssertionError:
Expected: a string starting with "xyz"
but: was "abc"

2. 햄크레스트 매처 살펴보기

2-1. 배열, 컬렉션 비교 - equalTo()

자바 배열, 컬렉션 객체를 비교할 때는 equalTo() 메서드를 사용한다.

   @Test
   public void comparesArraysFailing() {
      assertThat(new String[] {"a", "b", "c"}, equalTo(new String[] {"a", "b"}));
   }

–> 실패

   @Test
   public void comparesCollectionsFailing() {
      assertThat(Arrays.asList(new String[] {"a"}), 
            equalTo(Arrays.asList(new String[] {"a", "ab"})));
   }

–> 실패

   @Test
   public void comparesArraysPassing() {
      assertThat(new String[] {"a", "b"}, equalTo(new String[] {"a", "b"}));
   }

–> 성공

2-2. 가독성 높이기 - is 장식자

경우에 따라 is 장식자를 사용하여 가독성을 높힐 수 있음.

   @Test
   public void moreMatcherTests() {
      Account account = new Account(null);
      assertThat(account.getName(), is(nullValue()));
   }

2-3 불필요한 테스트코드

null이 아닌값을 검사하는건 불필요하고 가치가 없으니 되도록 이런 테스트코드는 짜지말것

      assertThat(account.getName(), is(not(nullValue())));
      assertThat(account.getName(), is(notNullValue()))

2-4. JUnit 햄크레스트 매처를 이용하여 할 수 있는것

  • 객체 타입 검사
  • 두 객체의 참조가 같은 인스턴스인지 검사
  • 다수의 매처를 결합해 둘다 or 1개라도 성공하는지 검사
  • 어떤 컬렉션이 요소를 포함하거나 조건에 부합하는지 검사
  • 어떤 컬렉션이 아이템 몇 개를 모두 포함하는지 검사
  • 어떤 컬렉션에 있는 모든 요소가 매처를 준수하는지 검사

2-5 부동소수점 비교

   @Test
   public void assertDoublesEqual() {
      assertThat(2.32 * 3, equalTo(6.96)); // Expected : <6.96> But was <6.599999999999>
   }

-> 실패하는 테스트. float 혹은 double을 비교할때는 두 수가 벌어질 수 있는 공차 또는 허용 오차를 지정해야함.

   @Test
   public void assertWithTolerance() {
      assertTrue(Math.abs((2.32 * 3) - 6.96) < 0.0005);
   }

안좋은예 -> 성공하긴 하는데 가독성이 구림.

   @Test
   public void assertDoublesCloseTo() {
      assertThat(2.32 * 3, closeTo(6.96, 0.0005));
   }

좋은예 -> isCloseTo라는 햄크레스트 매처 사용. 가독성이 훨씬 굿.

2-6 단언 설명

assertThat()에 첫번째 인자로 message를 넣어서 단언의 근거를 설명할 수 있음.

   @Test
   public void testWithWorthlessAssertionComment() {
      account.deposit(50);
      assertThat("account balance is 100", account.getBalance(), equalTo(50));
   }

근데 위의 예시처럼 잔액이 50인데 주석을 100으로 다는식의 실수가 있을수 있음.
따라서 위와 같이 주석문을 달기보다는, 테스트 코드 자체만으로 코드를 이해할 수 있게 하는것이 더 좋은 방법.

3. 예외 다루기

예외가 발생해야 테스트가 통과하는 케이스의 경우가있음.
그럴때는 아래와 같은 방식으로 테스트 코드를 짤 수 있다.

3-1. annotation 사용

   @Test(expected=InsufficientFundsException.class)
   public void throwsWhenWithdrawingTooMuch() {
      account.withdraw(100);
   }

-> InsufficientFundsException 에러가 발생하면 테스트 통과

3-2. try-catch 사용

   @Test
   public void throwsWhenWithdrawingTooMuchTry() {
      try {
         account.withdraw(100);
         fail();
      }
      catch (InsufficientFundsException expected) {
         assertThat(expected.getMessage(), equalTo("balance only 0"));
      }
   }

-> 옛날 방식. 예외가 안발생하면 fail() 메서드로 강제로 실패.

3-3. ExpectedException 사용

   @Rule
   public ExpectedException thrown = ExpectedException.none();  
   
   @Test
   public void exceptionRule() {
       // Assignment
      thrown.expect(InsufficientFundsException.class); 
      thrown.expectMessage("balance only 0");  
      
      // Act
      account.withdraw(100);  
   }

-> 최근방식. AOP 처럼 동작. @Rule로 규칙 인스턴스를 선언하고 셋업단계에서 테스트 실행시 발생할 수 있는 예외를 규칙 인스턴스에 알려줌. 실제로 withdraw 메서드를 실행했을때 기대한 예외와 메세지가 발생해야 테스트가 통과됨.

자바와 JUnit을 활용한 실용주의 단위테스트 책
https://github.com/gilbutITbook/006814






© 2020. by berrrrr

Powered by berrrrr