Skip to main content

Command Palette

Search for a command to run...

[JUnit] Assert에 대해 알아보자

Updated
[JUnit] Assert에 대해 알아보자
K

backend developer interested in technical problem

📝Assert

assertTrue

org.junit.Assert.assertTrue(someBooleanExpression);

단언은 JUnit 테스트에서 자주 사용되기 때문에 대부분 군더더기를 줄이고자 정적 import를 사용한다

import static org.junit.Assert.*;

//사용 예시
@Test
public void hasPositiveBalance(){
    account.deposit(50);
    assertTrue(account.hasPositiveBalance());
}

위에서 Account 인스턴스가 초기화 되어 있어야 한다.

@Before 메서드에서 Account 객체를 생성하고 참조를 테스트 클래스의 필드로 저장하면 된다.

assertThat

assertTrue가 참과 거짓을 구분한다면 assertThat은 명확한 값을 비교하는데 사용된다.

assertThat(account.getBalance(), equalTo(100));

햄크레스트 단언의 첫 번째 인자는 실제표현식 즉 우리가 검증하고자 하는 값이다.

두 번째 인자는 매처(matcher)이다. 매처는 실제 값과 표현식의 결과를 비교한다. 매처는 테스트 가독성을 크게 높여준다는 장점이 있다.

햄크레스트 매처를 사용하려면 코드에 정적 임포트를 추가해줘야한다.

import static.org.hamcrest.CoreMatchers.*;

equalTo 매처에는 어떤 자바 인스턴스나 기본형 값이라도 넣을 수 있다. equalTo매처는 비교 기준으로 equals()메서드를 사용한다.

자바 기본형은 객체형으로 오토 박싱 되기 때문에 어떤 타입도 비교할 수 있다.

일반적인 단언보다 햄크레스트 단언이 실패할 경우에 오류메세지에서 더 많은 정보를 알 수 있다. 앞의 테스트에서 기대값은 100인데 만약 101이 반환되면 오류메시지가 아래와 같이 나타난다.

//assertThat의 에러메시
java.lang.AssertionError:
Expected: <100> 
    but: was<101>

//전통적인 방식의 assertTrue의 에러메시지
...
java.lang.AssertionError
    at org.junit.Assert.fail(Asser.java:86)
...

따라서 assertTrue()보다 자세한 스택 트레이스를 보고 싶다면 다음과 같이 작성하면된다.

account.desposit(50);
assertThat(account.getBalance() > 0, is(true));

중요한 햄크레스트 매처 살펴보기

자바 배열 혹은 컬렉션 객체를 비교할 때는 equalTo() 메서드를 사용하며, 예상한대로 작동한다.

아래 에시를 보자

//실패하는 단언
assertThat(new String[] {"a", "b", "c"}, equalTo(new String[] {"a","b"}));
assertThat(Arrays.asList(new String[] {"a"}), equalTo(Arrays.asList(new String[] {"a","ab"})));

//통과하는 단언
assertThat(new String[] {"a", "b"}, equalTo(new String[] {"a", "b"}));
assertThat(Arrays.asList(new String[] {"a"}), equalTo(Arrays.asList(new String[] {"a"})));

//is를 사용해 가독성을 높인 단언 ~~취직하고싶다~~
Account account = new Account("want to get a job");
assertThat(account, is(equalTo("want to get a job")));

//부정할 때에는 not매처를 사용한다
assertThat(account.getName(),not(equalTo("i already have a job")));

//null 값을 검사할 때
assertThat(account.getName(), is(not(nullValue())));

경우에 따라 is 장식자를 추가하여 매처표현의 가독성을 더 높일 수도 있다. is는 단지 넘겨 받은 매처를 반환할 뿐이다.


🎲부동 소수점 비교

컴퓨터는 모든 부동소수점 수를 표현할 수 없기 때문에 부동소수점 타입(float, double 등)은 근사치로 구해야 한다. 단위 테스트에서 시사점은 두 부동소수점 수를 비교해도 항상 원하는 대로 나오지 않을 수 있다는 것이다.

//테스트를 통과할 것 같지만 실패하는 코드
assertThat(2.32 * 3, equalTo(6.96));

//아래처럼 에러가 나온다
java.lang.AssertionError:
Expected: <6.96>
but: was <6.599999999999>

따라서 두개의 float 혹은 double을 비교할 때는 허용 오차를 지정해야 한다. assertTrue()을 사용하여 다음과 같이 작성할 수 있다. 하지만 가독성이 별로다. 그래서 isCloseTo라는 햄크레스트 매처를 사용할 수 있다. 이 매처는 closeTo()정적 메서드를 제공한다.

//매처를 사용하지 않은 부동소수점 비교
assertTrue(Math.abs(2.32*3) - 6.96) < 0.0005);

//매처를 사용해 가독성을 높인 부동소수점 비교 단언
import static.org.hamcrest.number.IsCloseTo.*;
assertThat(2.32*3, closeTo(6.96, 0.0005));

하지만 가독성이 별로다.


🗨️단언 설명

모든 JUnit단언의 형식(전통적 fail(), 햄크레스트 assertThat()) 에는 message라는 선택적 첫 번째 인자가 있다. message 인자는 단언의 근거를 설명해 준다.

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

주석의 기대 잔고는 100 이지만 실제 코드의 기댓값은 50이다. 설명이 있는 주석문을 선호한다면 단언에 이처럼 메시지를 추가할 수 있다. 하지만 더 좋은 방법은 테스트를 코드 자체만으로 이해할 수 있게 작성하는 것!

참고

햄크레스트 매처에 대해 더 알아보고싶다면 API문서를 확인해보자

CoreMatchers (Hamcrest)

컴퓨터에서 부동소수점을 정확하게 구할 수 없는 이유 Why can't decimal numbers be represented exactly in binary?

150 views

More from this blog

rfc 959 읽어보면서 ftp이해하기

들어가며 프로젝트에서 FTP를 통해 파일을 전송하는 클라이언트를 개발했을 때 이야기입니다. 프로토콜에 대한 이해 없이 개발을 진행하다 보니 불필요하게 시간을 소모한 경험이 있어서 RFC 원문을 읽어보게 되었습니다. 읽게 된 계기 당시 FTP 프로토콜에 대한 이해가 부족한 상태로 개발을 시작했습니다. '제어를 위한 포트와 데이터 전송을 위한 포트가 분리되어 있다' 정도만 알고 있었고 Active 모드와 Passive 모드의 차이를 제대로 이해...

Dec 5, 20256
rfc 959 읽어보면서 ftp이해하기

mapstruct 로 보일러플레이트 코드 줄이기

배경 사내에서 교통 모니터링용 레이더 디바이스를 관리하는 API를 개발했을때 이야기입니다. 반복되는 코드에서 느꼈던 피로를 개선하고자 mapstruct를 적용해봤습니다. 실황 우선 일부 필드만 추출한 Device에 대해 간단히 이야기해야할 것 같습니다. 교통 모니터링용 레이더 디바이스로 신호등이나 가로등에 설치하며 설치된 좌표를 기록하는 위도, 경도와 레이더가 바라보는 방향을 의미하는 heading_angle필드 등이 있습니다. public...

Nov 13, 20259
mapstruct 로 보일러플레이트 코드 줄이기
T

takoyakisoba

38 posts