๐Ÿ“– ๊ณต์‹๋ฌธ์„œ์™€ ํ•จ๊ป˜ํ•˜๋Š” assertJ ์ •๋ฆฌ


JUnit5์œผ๋กœ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ assertion์„ ์ฃผ๋Š” ๋„๊ตฌ๋กœ assertJ๋ฅผ ๋ฐฐ์› ๋‹ค.
์ƒˆ๋กœ ๊นจ๋‹ซ๊ฒŒ ๋œ ๊ฒƒ์€ ์ •๋ฆฌํ•˜๋ฉฐ ์ตํžˆ์ž.

assertJ?

Java ํ…Œ์ŠคํŠธ์—์„œ ์œ ์ฐฝํ•˜๊ณ  ํ’๋ถ€ํ•œ assertions๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋ฐ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ง€์›

  • Standard Java
  • Java 8
  • Guava
  • Joda Time
  • Neo4J and
  • Swing components

Assertions ์ž‘์„ฑ

Assertions.assertThat()์— object๋ฅผ ์ „๋‹ฌํ•˜๋ฉด assertion์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

Obejct Assertions

Obejct๋Š” ๋‘ ๊ฐ์ฒด์˜ ๋™์ผ์„ฑ์ด๋‚˜ ๊ฐ์ฒด์˜ ํ•„๋“œ๋ฅผ ์กฐ์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.

Example

๋‘ Dog์˜ ๊ฐ์ฒด์ธ fido์™€ fidoClone์ด ์ฃผ์–ด์งˆ ๋•Œ

public class Dog { 
    private String name; 
    private Float weight;
    
    // standard getters and setters
}

Dog fido = new Dog("Fido", 5.25);

Dog fidosClone = new Dog("Fido", 5.25);

assertThat์„ ์ด์šฉํ•ด ๋น„๊ตํ•œ๋‹ค.

assertThat(fido).isEqualTo(fidosClone);

ํ•˜์ง€๋งŒ isEqualsTo()๊ฐ€ ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ๋น„๊ตํ•˜๋ฏ€๋กœ fail์ด๋‹ค.
๋‚ด์šฉ์„ ๋น„๊ตํ•˜๋ ค๋ฉด isEqualToComparingFieldByFieldRecursively()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

โœ๏ธ ์ฐธ๊ณ ๋กœ ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋ฉด์„œ ํŽ˜์–ด์—๊ฒŒ ๋“ค์—ˆ๋Š”๋ฐ assertEquals๋ณด๋‹ค assertThat์ด
์ข€ ๋” ์ง๊ด€์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๊ธ‰์  assertThat()์„ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ์•Œ๋ ค์คฌ๋‹ค.

Boolean Assertions

  • isTrue()
  • isFalse()
    assertThat("".isEmpty()).isTrue();
    

Iterable/Array Assertions

Iterable/Array์— ํŠน์ • ์š”์†Œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” ํŠน์ • ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

List<String> list = Arrays.asList("1", "2", "3");

assertThat(list).contains("1");

Example

list๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ

assertThat(list).isNotEmpty();

list๊ฐ€ ์ฃผ์–ด์ง„ ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ

assertThat(list).startsWith("1");

๋™์ผํ•œ ๊ฐ์ฒด์— ํ•˜๋‚˜ ์ด์ƒ์˜ assertion์„ ์ƒ์„ฑํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ฒด์ด๋‹์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

assertThat(list)
  .isNotEmpty()
  .contains("1")
  .doesNotContainNull()
  .containsSequence("2", "3");

Character Assertions

Character์— ๋Œ€ํ•œ assertions๋Š” ๋น„๊ต ๋Œ€์ƒ ๋ฌธ์ž๊ฐ€ ์œ ๋‹ˆ์ฝ”๋“œ ํ…Œ์ด๋ธ”์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์ž‘์—…์„ ํฌํ•จํ•œ๋‹ค.

Example

๋ฌธ์ž๊ฐ€ โ€˜aโ€™๊ฐ€ ์•„๋‹ˆ๊ณ  ์œ ๋‹ˆ์ฝ”๋“œ ํ…Œ์ด๋ธ”์— ์žˆ๋Š”์ง€, โ€˜bโ€™๋ณด๋‹ค ํฌ๊ณ  ์†Œ๋ฌธ์ž์ธ์ง€ ํ™•์ธํ•˜๋Š” assertion

assertThat(someCharacter)
  .isNotEqualTo('a')
  .inUnicode()
  .isGreaterThanOrEqualTo('b')
  .isLowerCase();

Class Assertions

ํ•ด๋‹น ํ•„๋“œ, ํด๋ž˜์Šค ์œ ํ˜•, annotations์˜ ์กด์žฌ ๋“ฑ์„ ์ฒดํฌํ•œ๋‹ค.

Example

ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ Runnable์ธ์ง€ ํ™•์ธ

assertThat(Runnable.class).isInterface();

ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ํ• ๋‹น ๊ฐ€๋Šฅํ•œ์ง€ ํ™•์ธ

assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

File Assertions

์ง€์ •๋œ File ์ธ์Šคํ„ด์Šค๊ฐ€ ์กด์žฌ ํ•˜๋Š”์ง€, ๋””๋ ‰ํ† ๋ฆฌ ๋˜๋Š” ํŒŒ์ผ์ธ์ง€,
ํŠน์ • ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ๋Š”์ง€, ์ฝ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ๋˜๋Š” ํ™•์žฅ๋ช…์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

Example

ํŒŒ์ผ์ด ์กด์žฌํ•˜๊ณ , ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์ด๋ฉฐ, ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ

 assertThat(someFile)
   .exists()
   .isFile()
   .canRead()
   .canWrite();

Double / Float / Integer Assertions

์ฃผ์–ด์ง„ Offset ์•ˆ์—์„œ ํ˜น์€ ์—†๋Š” ์ˆซ์ž ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค.

assertThat(5.1).isEqualTo(5, withPrecision(1d));

InputStream Assertions

  • hasSameContentAs(InputStream expected)
    assertThat(given).hasSameContentAs(expected);
    

Map Assertions

๋งต์— ํŠน์ • ํ•ญ๋ชฉ, entry, key/value ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

Example

๋งต์ด ๋น„์–ด์žˆ์ง€ ์•Š๊ณ  ํ‚ค 2๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ํ‚ค 10์„ ํฌํ•จํ•˜์ง€ ์•Š๊ณ  (2, โ€œaโ€)๋ฅผ ํฌํ•จํ•˜๋Š”์ง€ ํ™•์ธ

assertThat(map)
  .isNotEmpty()
  .containsKey(2)
  .doesNotContainKeys(10)
  .contains(entry(2, "a"));

Throwable Assertions

์˜ˆ์™ธ ๋ฉ”์‹œ์ง€, ์Šคํƒ ์ถ”์  ๊ฒ€์‚ฌ, ์˜ˆ์™ธ๊ฐ€ ์ด๋ฏธ throw ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

Example

์ฃผ์–ด์ง„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  โ€œcโ€๋กœ ๋๋‚˜๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ

assertThat(ex).hasNoCause().hasMessageEndingWith("c");

๊ต์œก์—์„œ ์ด Throwable Assertions๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผฐ๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.
assertThatThrownBy()์™€ assertThatExceptionOfType() ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•จ์„ ๊นจ๋‹ฌ์•˜๋‹ค.

  • assertThatThrownBy() : Java 8 exception assertion ํ‘œ์ค€ ์Šคํƒ€์ผ
  • assertThatExceptionOfType() : ์˜ˆ์™ธ ํด๋ž˜์Šค ๋„ฃ๊ธฐ ``` @Test @DisplayName(โ€œํŠน์ • ์œ„์น˜ ๋ฌธ์ž ๊ฐ€์ ธ์˜ค๊ธฐ hasโ€) public void charGetFromString1() { String name = โ€œFortuneโ€; int index = 10;

    assertThatThrownBy(() -> { name.charAt(index); }).isInstanceOf(IndexOutOfBoundsException.class) .hasMessageContaining(โ€œ%dโ€, index); }

@Test @DisplayName(โ€œํŠน์ • ์œ„์น˜ ๋ฌธ์ž ๊ฐ€์ ธ์˜ค๊ธฐ withโ€) public void charGetFromString2() { String name = โ€œFortuneโ€; int index = 10;

assertThatExceptionOfType(IndexOutOfBoundsException.class)
        .isThrownBy(() -> {
            name.charAt(index);
        }).withMessageContaining("%d", index); } ```

java8์—์„œ ๋” ์œ ์šฉํ•˜๊ฒŒ. . .

  • java7
    assertThat(fellowshipOfTheRing)
    .filteredOn("race", HOBBIT)
    .containsOnly(sam, frodo, pippin, merry);
    
  • java8
    assertThat(fellowshipOfTheRing)
    .filteredOn(character -> character.getRace().equals(HOBBIT))
    .containsOnly(sam, frodo, pippin, merry);
    

์ฐธ๊ณ ์ž๋ฃŒ