Skip to content

Latest commit

ย 

History

History
498 lines (381 loc) ยท 15.9 KB

File metadata and controls

498 lines (381 loc) ยท 15.9 KB

๋ณธ ๊ธ€์€ AssertJ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ฒˆ์—ญํ•˜๋ฉฐ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

์ „์ฒด ๋‚ด์šฉ์„ ๋ชจ๋‘ ๋ฒˆ์—ญํ•˜์ง„ ์•Š์•˜์œผ๋ฏ€๋กœ, ํ•„์š”ํ•˜์‹  ๋ถ„์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ๋ฐ”๋ž๋‹ˆ๋‹ค.

AssertJ Core ์ •๋ฆฌ



1 AssertJ ๋ž€?

AssertJ๋ž€ ๋งŽ์€ assertion์™€ ๋„์›€๋˜๋Š” ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ๋˜ํ•œ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ฃผ๋ฉฐ, ์ข‹์•„ํ•˜๋Š” IDE์—์„œ ์“ฐ๊ธฐ ๊ต‰์žฅํžˆ ์‰ฝ๋‹ค.


์˜ˆ์‹œ

// entry point for all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;

// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);

// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
                           .endsWith("do")
                           .isEqualToIgnoringCase("frodo");

// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo, sam)
                               .doesNotContain(sauron);

// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);

// exception assertion, standard style ...
assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!");
// ... or BDD style
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
assertThat(thrown).hasMessageContaining("boom");

// using the 'extracting' feature to check fellowshipOfTheRing character's names
assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName)
                               .doesNotContain("Sauron", "Elrond");

// extracting multiple values at once grouped in tuples
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
                               .contains(tuple("Boromir", 37, "Man"),
                                         tuple("Sam", 38, "Hobbit"),
                                         tuple("Legolas", 1000, "Elf"));

// filtering a collection before asserting
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                               .containsOnly(aragorn, frodo, legolas, boromir);

// combining filtering and extraction (yes we can)
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                               .containsOnly(aragorn, frodo, legolas, boromir)
                               .extracting(character -> character.getRace().getName())
                               .contains("Hobbit", "Elf", "Man");

// and many more assertions: iterable, stream, array, map, dates, path, file, numbers, predicate, optional ...

2 Quick Start

maven๊ณผ gradle์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฒ„์ „์€ ์ตœ์‹ ํ™”๊ฐ€ ๊ณ„์† ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์œผ๋ฉฐ java 8 ์ด์ „ ๋ฒ„์ „์˜ ๊ฒฝ์šฐ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.


2-1 Maven

<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <!-- use 2.9.1 for Java 7 projects -->
  <version>3.19.0</version>
  <scope>test</scope>
</dependency>

2-2 Gradle

testImplementation("org.assertj:assertj-core:3.19.0")

2-3 Assertions

Assertions ํด๋ž˜์Šค๋Š” AssertJ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์œ ์ผํ•œ ํด๋ž˜์Šค๋กœ ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.

๋Œ€์•ˆ์œผ๋กœ, ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค๊ฐ€ WithAssertions๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉฐ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋“ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

// Assertions
import static org.assertj.core.api.Assertions.*;
// WithAssertions
import org.assertj.core.api.WithAssertions;

public class WithAssertionsExamples extends AbstractAssertionsExamples implements WithAssertions {

  // the data used are initialized in AbstractAssertionsExamples.

  @Test
  public void withAssertions_examples() {

    // assertThat methods come from WithAssertions - no static import needed
    assertThat(frodo.age).isEqualTo(33);
    assertThat(frodo.getName()).isEqualTo("Frodo").isNotEqualTo("Frodon");

    assertThat(frodo).isIn(fellowshipOfTheRing);
    assertThat(frodo).isIn(sam, frodo, pippin);
    assertThat(sauron).isNotIn(fellowshipOfTheRing);

    assertThat(frodo).matches(p -> p.age > 30 && p.getRace() == HOBBIT);
    assertThat(frodo.age).matches(p -> p > 30);
  }
}

3 ์ฃผ์š” Assertions

์ด ์„น์…˜์—์„œ๋Š” AssertJ์—์„œ ์ œ๊ณตํ•˜๋Š” Assertions์™€ ์ด๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐํƒ€ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์„ค๋ช…ํ•œ๋‹ค.

AssertJ Core javadoc์€ ๋Œ€๋ถ€๋ถ„์˜ Assertions์„ ์ฝ”๋“œ ์˜ˆ์ œ๋กœ ์„ค๋ช…ํ•˜๋ฏ€๋กœ ํŠน์ • Assertions์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.


3-1 ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ

public class SimpleAssertionsExample {
    @Test
    void a_few_simple_assertions() {
        assertThat("The Lord of the Rings").isNotNull()
                                           .startsWith("The")
                                           .contains("Lord")
                                           .endsWith("Rings");
    }
}

๋”ฑ ๋ด๋„ ๊ฐ€๋…์„ฑ์ด ๊ต‰์žฅํžˆ ์ข‹๋‹ค.

๊ธฐ๋ณธ assertion์ธ isNotNull์„ ์ œ์™ธํ•˜๊ณ , ๋‹ค๋ฅธ assertion์€ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ๊ฐœ์ฒด๊ฐ€ String์ด๋ฏ€๋กœ ๋ฌธ์ž์—ด์—๋งŒ ํ•œ์ •๋œ๋‹ค.


3-2 ์ œ๊ณต๋˜๋Š” ํƒ€์ž… assertions

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธ.


3-3 Assertion description

AssertJ๋Š” ํ…Œ์ŠคํŠธ ์‹คํŒจ ์‹œ ๋‚˜ํƒ€๋‚ผ ๋ฉ”์‹œ์ง€๋ฅผ as๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

as๋Š” ๊ฒ€์ฆ ๋ฌธ ์•ž์— ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ๋’ค์— ์ž‘์„ฑ ์‹œ ๋ฌด์‹œ๋œ๋‹ค.

TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, Race.HOBBIT);

// failing assertion, remember to call as() before the assertion!
assertThat(frodo.getAge()).as("check %s's age", frodo.getName())
                          .isEqualTo(100);
// Error Message
[check Frodo's age] expected:<100> but was:<33>

3-4 ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์žฌ์ •์˜

AssertJ๋Š” ์ด๋ฏธ ์œ ์šฉํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ํ•ญ์ƒ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • OverridingErrorMessage()
  • WithFailMessage()
TolkienCharacter frodo = new TolkienCharacter("Frodo", 33, Race.HOBBIT);
TolkienCharacter sam = new TolkienCharacter("Sam", 38, Race.HOBBIT);
// failing assertion, remember to call withFailMessage/overridingErrorMessage before the assertion!
assertThat(frodo.getAge()).withFailMessage("should be %s", frodo)
                          .isEqualTo(sam);
// Error Message
java.lang.AssertionError: should be TolkienCharacter [name=Frodo, age=33, race=HOBBIT]

Lazy error message overriding ๋งŒ์•ฝ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ ๋น„์šฉ์ด ๋น„์‹ธ๋‹ค๋ฉด, String ๋Œ€์‹ ์— Supplier(String)์„ ์‚ฌ์šฉํ•ด์„œ ์žฌ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด assertion fails์—๋งŒ ๋ฉ”์‹œ์ง€๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

assertThat(player.isRookie()).overridingErrorMessage(() -> "Expecting Player to be a rookie but was not.")
                             .isTrue();

assertThat(player.isRookie()).withFailMessage(() -> "Expecting Player to be a rookie but was not.")
                             .isTrue();

3-5 ์ž˜๋ชป๋œ ์‚ฌ์šฉ๋ฒ•์„ ํ”ผํ•˜๋ผ

// BAD
assertThat(actual.equals(expected));

// GOOD
assertThat(actual).isEqualTo(expected);

assertThat(actual.equals(expected)).isTrue();
// BAD
assertThat(1 == 2);

// GOOD
assertThat(1).isEqualTo(2);

assertThat(1 == 2).isTrue();
// BAD
assertThat(actual).isEqualTo(expected).as("description");
assertThat(actual).isEqualTo(expected).describedAs("description");

// GOOD
assertThat(actual).as("description").isEqualTo(expected);
assertThat(actual).describedAs("description").isEqualTo(expected);
// BAD
assertThat(actual).isEqualTo(expected).overridingErrorMessage("custom error message");
assertThat(actual).isEqualTo(expected).withFailMessage("custom error message");

// GOOD
assertThat(actual).overridingErrorMessage("custom error message").isEqualTo(expected);
assertThat(actual).withFailMessage("custom error message").isEqualTo(expected);
// BAD
assertThat(actual).isEqualTo(expected).usingComparator(new CustomComparator());

// GOOD
assertThat(actual).usingComparator(new CustomComparator()).isEqualTo("a");

3-6 AssertJ ์„ค์ •

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธ.


3-7 String/CharSequence assertions

์ด ์„น์…˜์€ CharSequence(including String, StringBuilder, StringBuffer, ...)์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” assertions์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ javadoc์—์„œ ํ™•์ธ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


3-8 contains


Checking iterables/arrays content - contains ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” ๋ถ€์ •๋ฌธ์ด ์กด์žฌํ•œ๋‹ค. (doesNotContains)


contains

 List<String> abc = Arrays.asList("a", "b", "c");

 // ์„ฑ๊ณต
 assertThat(abc).contains("b", "a");
 assertThat(abc).contains("b", "a", "b");

 // ์‹คํŒจ
 assertThat(abc).contains("d");

containsOnly

List<String> list = Arrays.asList("one", "two", "three", "four");

// ์ˆœ์„œ์™€ ์ƒ๊ด€์—†์ด ์„ฑ๊ณต
assertThat(list).containsOnly("three", "two", "one", "four");
// ์ค‘๋ณต์€ ๋ฌด์‹œ๋œ๋‹ค
assertThat(list).containsOnly("three", "two", "two", "one", "four");

// four๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์‹คํŒจ
assertThat(list).containsOnly("three", "two", "one");
// five๊ฐ€ list์— ์—†์œผ๋ฏ€๋กœ ์‹คํŒจ
assertThat(list).containsOnly("three", "two", "one", "four", "five");

containsExactly

List<String> list = Arrays.asList("one", "two", "three", "four");

// ์„ฑ๊ณต
assertThat(list).containsExactly("one", "two", "three", "four");

// ์‹คํŒจ (์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๋‹ค)
assertThat(list).containsExactly("four", "three", "two", "one");
  • ์ˆœ์„œ์™€ ์ƒ๊ด€ ์—†์ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด containsExactlyInAnyOrder์„ ์‚ฌ์šฉ.

containsSequence

List<String> list = Arrays.asList("one", "two", "three", "four");

// ์„ฑ๊ณต
assertThat(list).containsSequence("one", "two");
assertThat(list).containsSequence("one", "two")
                .containsSequence("three", "four");

// ์‹คํŒจ
assertThat(list).containsSequence("one", "three")
                .containsSequence("two", "four");
  • ์ˆœ์„œ๋Œ€๋กœ ๊ทธ๋ฃนํ•‘์„ ํ•˜๊ณ  ์žˆ๋‚˜ ํ™•์ธํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ํ•œ๋‹ค.
    • actual์™€ given์ด ๋ชจ๋‘ ๋ฆฌ์ŠคํŠธ(์ปฌ๋ ‰์…˜)์ธ ๊ฒฝ์šฐ containsSubSequence๋ฅผ ์‚ฌ์šฉํ•˜์ž

containsOnlyOne

// assertions will pass
 assertThat(newArrayList("winter", "is", "coming")).containsOnlyOnce("winter");
 assertThat(newArrayList("winter", "is", "coming")).containsOnlyOnce("coming", "winter");

 // assertions will fail
 assertThat(newArrayList("winter", "is", "coming")).containsOnlyOnce("Lannister");
 assertThat(newArrayList("Arya", "Stark", "daughter", "of", "Ned", "Stark")).containsOnlyOnce("Stark");
 assertThat(newArrayList("Arya", "Stark", "daughter", "of", "Ned", "Stark")).containsOnlyOnce("Stark", "Lannister", "Arya");
  • actual ๊ทธ๋ฃน์ด given ๊ฐ’์„ ๋”ฑ ํ•œ๋ฒˆ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ํ…Œ์ŠคํŠธ

containsAnyOf

List<String> list = Arrays.asList("one", "two", "three", "four");

// ์„ฑ๊ณต
assertThat(list).containsAnyOf("three")
                .containsAnyOf("two", "one")
                .containsAnyOf("one", "two", "three")
                .containsAnyOf("one", "two", "three", "four", "five")
                .containsAnyOf("four", "five", "six", "seven");

// ์‹คํŒจ
assertThat(list).containsAnyOf("five")
                .containsAnyOf("five", "six", "seven", "eight");
  • ์š”์†Œ์˜ ๊ฐ’์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” assertion

3-9 Satisfy

๋ชจ๋“  ์š”์†Œ๋‚˜ ํ˜น์€ ์•„๋ฌด ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ assertion์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์–ด์ง€๋Š” assertion์€ Consumer๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.

  • allSatisfy
  • anySatisfy
  • noneSatisfy
List<Person> list = Arrays.asList(new Person("frodo", 5),
                                          new Person("pippin", 5),
                                          new Person("sam", 5));

// ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ assertion์„ ๋ชจ๋‘ ๋งŒ์กฑํ•ด์•ผํ•œ๋‹ค.
assertThat(list).allSatisfy(person -> {
    assertThat(person.getAge()).isEqualTo(5);
});

// ์ ์–ด๋„ ํ•˜๋‚˜์˜ ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ assertion์„ ๋งŒ์กฑํ•ด์•ผํ•œ๋‹ค.
assertThat(list).anySatisfy(person -> {
    assertThat(person.getAge()).isEqualTo(5);
    assertThat(person.getName()).isEqualTo("sam");
});

// ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ assertion์„ ๋งŒ์กฑํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
assertThat(list).noneSatisfy(person -> {
    assertThat(person.getName()).isEqualTo("none");
    assertThat(person.getAge()).isEqualTo(10);
});

3-10 Match

๋ชจ๋“  ์š”์†Œ๋‚˜ ํ˜น์€ ์•„๋ฌด ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ assertion์— ๋ถ€ํ•ฉํ•œ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์–ด์ง„ assertion์€ Predicate๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.

  • allMatch
  • anyMatch
  • noneMatch
List<Person> list = Arrays.asList(new Person("frodo", 5),
                                          new Person("pippin", 5),
                                          new Person("sam", 5));

assertThat(list).allMatch(person -> person.getAge() == 5, "age")
                .anyMatch(person -> person.getName().contains("fro"))
                .noneMatch(person -> person.getName().contains("b"));

3-11 First/Last/Element

first, last, elements(index)๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€๋ฆฌํ‚จ ํ›„, ์•„๋ž˜ ์˜ˆ์ œ์— ํ‘œ์‹ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ Assert ํด๋ž˜์Šค ํ˜น์€ InstanceOfAssertFactory๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ์ฒด assertion์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
List<String> list = Arrays.asList("frodo", "sam", "pippin");

// ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
assertThat(list).first().isEqualTo("frodo");
assertThat(list).element(1).isEqualTo("sam");
assertThat(list).last().isEqualTo("pippin");

// ๋ฌธ์ž์—ด ํ™œ์šฉ
assertThat(list).first(as(STRING))
                .startsWith("fro")
                .endsWith("do");
assertThat(list).element(1, as(STRING))
                .startsWith("sa")
                .endsWith("am");
assertThat(list).last(as(STRING))
                .startsWith("pipp")
                .endsWith("ppin");

Single elements

List<String> list = Arrays.asList("frodo");

assertThat(list).singleElement()
                .isEqualTo("frodo");

assertThat(list).singleElement(as(STRING))
                .endsWith("do");
  • Single elements๋กœ ํ•˜๋‚˜์˜ ์š”์†Œ๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋‹ค.

3-12 filter