๋ณธ ๊ธ์ AssertJ ๊ณต์ ๋ฌธ์๋ฅผ ๋ฒ์ญํ๋ฉฐ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
์ ์ฒด ๋ด์ฉ์ ๋ชจ๋ ๋ฒ์ญํ์ง ์์์ผ๋ฏ๋ก, ํ์ํ์ ๋ถ์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ๋ฐ๋๋๋ค.
- AssertJ Core ์ ๋ฆฌ
- 1 AssertJ ๋?
- 2 Quick Start
- 3 ์ฃผ์ Assertions
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 ...maven๊ณผ gradle์ ํตํด ์ฝ๊ฒ ์์ํ ์ ์๋ค.
๋ฒ์ ์ ์ต์ ํ๊ฐ ๊ณ์ ์ด๋ฃจ์ด์ง๊ณ ์์ผ๋ฉฐ java 8 ์ด์ ๋ฒ์ ์ ๊ฒฝ์ฐ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.
<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>testImplementation("org.assertj:assertj-core:3.19.0")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);
}
}์ด ์น์ ์์๋ AssertJ์์ ์ ๊ณตํ๋ Assertions์ ์ด๋ฅผ ์ต๋ํ ํ์ฉํ๊ธฐ ์ํ ๊ธฐํ ์ ์ฉํ ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ค.
AssertJ Core javadoc์ ๋๋ถ๋ถ์ Assertions์ ์ฝ๋ ์์ ๋ก ์ค๋ช ํ๋ฏ๋ก ํน์ Assertions์ด ๋ฌด์์ธ์ง ์๊ณ ์ถ๋ค๋ฉด ํ์ธํ๋ฉด ๋๋ค.
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์ด๋ฏ๋ก ๋ฌธ์์ด์๋ง ํ์ ๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ์์ ํ์ธ.
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>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();// 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");์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ์์ ํ์ธ.
์ด ์น์
์ CharSequence(including String, StringBuilder, StringBuffer, ...)์ ๋ํด ์ฌ์ฉํ ์ ์๋ assertions์ ๋ค๋ฃน๋๋ค.
์์ธํ ๋ด์ฉ์ javadoc์์ ํ์ธ๊ฐ๋ฅํฉ๋๋ค.
Checking iterables/arrays content - contains
๋ชจ๋ ๋ฉ์๋๋ ๋ถ์ ๋ฌธ์ด ์กด์ฌํ๋ค. (doesNotContains)
List<String> abc = Arrays.asList("a", "b", "c");
// ์ฑ๊ณต
assertThat(abc).contains("b", "a");
assertThat(abc).contains("b", "a", "b");
// ์คํจ
assertThat(abc).contains("d");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");List<String> list = Arrays.asList("one", "two", "three", "four");
// ์ฑ๊ณต
assertThat(list).containsExactly("one", "two", "three", "four");
// ์คํจ (์์๊ฐ ๋ค๋ฅด๋ค)
assertThat(list).containsExactly("four", "three", "two", "one");- ์์์ ์๊ด ์์ด ํ
์คํธ๋ฅผ ํ๊ณ ์ ํ๋ค๋ฉด
containsExactlyInAnyOrder์ ์ฌ์ฉ.
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๋ฅผ ์ฌ์ฉํ์
- actual์ given์ด ๋ชจ๋ ๋ฆฌ์คํธ(์ปฌ๋ ์
)์ธ ๊ฒฝ์ฐ
// 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 ๊ฐ์ ๋ฑ ํ๋ฒ๋ง ๊ฐ์ง๊ณ ์๋ค๋ ํ ์คํธ
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
๋ชจ๋ ์์๋ ํน์ ์๋ฌด ์์๊ฐ ์ฃผ์ด์ง assertion์ ๋ง์กฑํ๋์ง ํ์ธํ ์ ์๋ค.
์ฃผ์ด์ง๋ assertion์ Consumer๋ก ๋ํ๋ธ๋ค.
allSatisfyanySatisfynoneSatisfy
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);
});๋ชจ๋ ์์๋ ํน์ ์๋ฌด ์์๊ฐ ์ฃผ์ด์ง assertion์ ๋ถํฉํ์ง ํ์ธํ ์ ์๋ค.
์ฃผ์ด์ง assertion์ Predicate๋ก ๋ํ๋ธ๋ค.
allMatchanyMatchnoneMatch
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"));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๋ก ํ๋์ ์์๋ง์ ๊ฐ์ง๊ณ ์์์ ์ฒดํฌํ ์ ์๋ค.