diff --git a/testing/pom.xml b/testing/pom.xml
index 0bc70bdb96..a0bc5b99cf 100644
--- a/testing/pom.xml
+++ b/testing/pom.xml
@@ -52,6 +52,18 @@
${pitest.version}
pom
+
+
+ com.google.truth
+ truth
+ ${truth.version}
+
+
+ com.google.truth.extensions
+ truth-java8-extension
+ ${truth.version}
+ test
+
@@ -114,8 +126,9 @@
1.2.5
1.1.10
0.7.7.201606060606
- 19.0
+ 21.0
3.1.0
3.6.1
+ 0.32
diff --git a/testing/src/main/java/com/baeldung/testing/truth/User.java b/testing/src/main/java/com/baeldung/testing/truth/User.java
new file mode 100644
index 0000000000..fe857dd265
--- /dev/null
+++ b/testing/src/main/java/com/baeldung/testing/truth/User.java
@@ -0,0 +1,57 @@
+package com.baeldung.testing.truth;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+public class User implements Comparable {
+ private String name = "John Doe";
+ private List emails = Arrays.asList("contact@baeldung.com", "staff@baeldung.com");
+
+ public User() {
+ }
+
+ public User(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getEmails() {
+ return emails;
+ }
+
+ public void setEmails(List emails) {
+ this.emails = emails;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 37 * hash + Objects.hashCode(this.name);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final User other = (User) obj;
+ return Objects.equals(this.name, other.name);
+ }
+
+ @Override
+ public int compareTo(User o) {
+ return this.getName()
+ .compareToIgnoreCase(o.getName());
+ }
+
+}
diff --git a/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java b/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java
new file mode 100644
index 0000000000..2fd84085a0
--- /dev/null
+++ b/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java
@@ -0,0 +1,46 @@
+package com.baeldung.testing.truth;
+
+import com.google.common.truth.ComparableSubject;
+import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.IterableSubject;
+import com.google.common.truth.SubjectFactory;
+import com.google.common.truth.Truth;
+
+public class UserSubject extends ComparableSubject {
+
+ private UserSubject(FailureStrategy failureStrategy, User target) {
+ super(failureStrategy, target);
+ }
+
+ private static final SubjectFactory USER_SUBJECT_FACTORY = new SubjectFactory() {
+ @Override
+ public UserSubject getSubject(FailureStrategy failureStrategy, User target) {
+ return new UserSubject(failureStrategy, target);
+ }
+ };
+
+ public static UserSubject assertThat(User user) {
+ return Truth.assertAbout(USER_SUBJECT_FACTORY)
+ .that(user);
+ }
+
+ // Our API begins here
+ public void hasName(String name) {
+ if (!actual().getName()
+ .equals(name)) {
+ fail("has name", name);
+ }
+ }
+
+ public void hasNameIgnoringCase(String name) {
+ if (!actual().getName()
+ .equalsIgnoreCase(name)) {
+ fail("has name ignoring case", name);
+ }
+ }
+
+ public IterableSubject emails() {
+ return Truth.assertThat(actual().getEmails());
+ }
+
+}
\ No newline at end of file
diff --git a/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java
new file mode 100644
index 0000000000..dfda21d99a
--- /dev/null
+++ b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java
@@ -0,0 +1,561 @@
+package com.baeldung.testing.truth;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Range;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeBasedTable;
+import com.google.common.collect.TreeMultiset;
+import static com.baeldung.testing.truth.UserSubject.*;
+import static com.google.common.truth.Truth.*;
+import static com.google.common.truth.Truth8.*;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class GoogleTruthUnitTest {
+
+ @Test
+ public void whenComparingInteger_thenEqual() {
+ int anInt = 10;
+
+ assertThat(anInt).isEqualTo(10);
+ }
+
+ @Test
+ public void whenComparingFloat_thenIsBigger() {
+ float aFloat = 10.0f;
+
+ assertThat(aFloat).isGreaterThan(1.0f);
+ }
+
+ @Test
+ public void whenComparingDouble_thenIsSmaller() {
+ double aDouble = 10.0f;
+
+ assertThat(aDouble).isLessThan(20.0);
+ }
+
+ @Test
+ public void whenComparingFloat_thenWithinPrecision() {
+ float aFloat = 23.04f;
+
+ assertThat(aFloat).isWithin(1.3f)
+ .of(23.3f);
+ }
+
+ @Test
+ public void whenComparingFloat_thenNotWithinPrecision() {
+ float aFloat = 23.04f;
+
+ assertThat(aFloat).isNotWithin(1.3f)
+ .of(100f);
+ }
+
+ @Test
+ public void whenComparingDouble_thenWithinPrecision() {
+ double aDouble = 22.18;
+
+ assertThat(aDouble).isWithin(2)
+ .of(23d);
+ }
+
+ @Test
+ public void whenComparingDouble_thenNotWithinPrecision() {
+ double aDouble = 22.08;
+
+ assertThat(aDouble).isNotWithin(2)
+ .of(100);
+ }
+
+ @Test
+ public void whenComparingBigDecimal_thenEqualIgnoringScale() {
+ BigDecimal aBigDecimal = BigDecimal.valueOf(1000, 3);
+
+ assertThat(aBigDecimal).isEqualToIgnoringScale(new BigDecimal(1.0));
+ }
+
+ @Test
+ public void whenChekingBoolean_thenTrue() {
+ boolean aBoolean = true;
+
+ assertThat(aBoolean).isTrue();
+ }
+
+ @Test
+ public void whenChekingBoolean_thenFalse() {
+ boolean aBoolean = false;
+
+ assertThat(aBoolean).isFalse();
+ }
+
+ @Test
+ public void whenComparingArrays_thenEqual() {
+ String[] firstArrayOfStrings = { "one", "two", "three" };
+ String[] secondArrayOfStrings = { "one", "two", "three" };
+
+ assertThat(firstArrayOfStrings).isEqualTo(secondArrayOfStrings);
+ }
+
+ @Test
+ public void whenComparingArrays_thenNotEqual() {
+ String[] firstArrayOfStrings = { "one", "two", "three" };
+ String[] secondArrayOfStrings = { "three", "two", "one" };
+
+ assertThat(firstArrayOfStrings).isNotEqualTo(secondArrayOfStrings);
+ }
+
+ @Test
+ public void whenCheckingArray_thenEmpty() {
+ Object[] anArray = {};
+
+ assertThat(anArray).isEmpty();
+ }
+
+ @Test
+ public void whenCheckingArray_thenNotEmpty() {
+ String[] arrayOfStrings = { "One String " };
+
+ assertThat(arrayOfStrings).isNotEmpty();
+ }
+
+ @Test
+ public void whenCheckingArrayOfDoubles_thenWithinPrecision() {
+ double[] arrayOfDoubles = { 1, 2, 3, 4, 5 };
+
+ assertThat(arrayOfDoubles).hasValuesWithin(5)
+ .of(6, 7, 8, 9, 10);
+ }
+
+ @Test
+ public void whenComparingUsers_thenEqual() {
+ User aUser = new User("John Doe");
+ User anotherUser = new User("John Doe");
+
+ assertThat(aUser).isEqualTo(anotherUser);
+ }
+
+ @Test
+ public void whenComparingUser_thenIsNull() {
+ User aUser = null;
+
+ assertThat(aUser).isNull();
+ }
+
+ @Test
+ public void whenComparingUser_thenNotNull() {
+ User aUser = new User();
+
+ assertThat(aUser).isNotNull();
+ }
+
+ @Test
+ public void whenComparingUser_thenInstanceOf() {
+ User aUser = new User();
+
+ assertThat(aUser).isInstanceOf(User.class);
+ }
+
+ @Test
+ public void whenComparingUser_thenInList() {
+ User aUser = new User();
+
+ assertThat(aUser).isIn(Arrays.asList(1, 3, aUser, null));
+ }
+
+ @Test
+ public void whenComparingUser_thenNotInList() {
+ User aUser = new User();
+
+ assertThat(aUser).isNotIn(Arrays.asList(1, 3, "Three"));
+ }
+
+ @Test
+ public void whenComparingNullUser_thenInList() {
+ User aUser = null;
+ User anotherUser = new User();
+
+ assertThat(aUser).isIn(Arrays.asList(1, 3, anotherUser, null));
+ }
+
+ @Test
+ public void whenChekingString_thenStartsWithString() {
+ String aString = "This is a string";
+
+ assertThat(aString).startsWith("This");
+ }
+
+ @Test
+ public void whenChekingString_thenContainsString() {
+ String aString = "This is a string";
+
+ assertThat(aString).contains("is a");
+ }
+
+ @Test
+ public void whenChekingString_thenEndsWithString() {
+ String aString = "This is a string";
+
+ assertThat(aString).endsWith("string");
+ }
+
+ @Test
+ public void whenChekingString_thenExpectedLength() {
+ String aString = "This is a string";
+
+ assertThat(aString).hasLength(16);
+ }
+
+ @Test
+ public void whenChekingString_thenEmpty() {
+ String aString = "";
+
+ assertThat(aString).isEmpty();
+ }
+
+ @Test
+ public void whenChekingString_thenMatches() {
+ String aString = "The string to match";
+
+ assertThat(aString).matches(Pattern.compile("[a-zA-Z\\s]+"));
+ }
+
+ @Test
+ public void whenCheckingComparable_thenAtLeast() {
+ Comparable aComparable = 5;
+
+ assertThat(aComparable).isAtLeast(1);
+ }
+
+ @Test
+ public void whenCheckingComparable_thenAtMost() {
+ Comparable aComparable = 5;
+
+ assertThat(aComparable).isAtMost(10);
+ }
+
+ @Test
+ public void whenCheckingComparable_thenInList() {
+ Comparable aComparable = 5;
+
+ assertThat(aComparable).isIn(Arrays.asList(4, 5, 6));
+ }
+
+ @Test
+ public void whenCheckingComparable_thenInRange() {
+ Comparable aComparable = 5;
+
+ assertThat(aComparable).isIn(Range.closed(1, 10));
+ }
+
+ @Test
+ public void whenCheckingComparable_thenNotInRange() {
+ Comparable aComparable = 5;
+
+ assertThat(aComparable).isNotIn(Range.closed(10, 15));
+ }
+
+ @Test
+ public void whenComparingUsers_thenEquivalent() {
+ User aUser = new User();
+ aUser.setName("John Doe");
+
+ User anotherUser = new User();
+ anotherUser.setName("john doe");
+
+ assertThat(aUser).isEquivalentAccordingToCompareTo(anotherUser);
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContains() {
+ List aList = Arrays.asList(4, 5, 6);
+
+ assertThat(aList).contains(5);
+ }
+
+ @Test
+ public void whenCheckingIterable_thenDoesNotContains() {
+ List aList = Arrays.asList(4, 5, 6);
+
+ assertThat(aList).doesNotContain(9);
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContainsAny() {
+ List aList = Arrays.asList(4, 5, 6);
+
+ assertThat(aList).containsAnyOf(0, 5, 10);
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContainsAnyInList() {
+ List aList = Arrays.asList(1, 2, 3);
+
+ assertThat(aList).containsAnyIn(Arrays.asList(1, 5, 10));
+ }
+
+ @Test
+ public void whenCheckingIterable_thenNoDuplicates() {
+ List aList = Arrays.asList(-2, -1, 0, 1, 2);
+
+ assertThat(aList).containsNoDuplicates();
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContainsNoneOf() {
+ List aList = Arrays.asList(4, 5, 6);
+
+ assertThat(aList).containsNoneOf(9, 8, 7);
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContainsNoneIn() {
+ List aList = Arrays.asList(4, 5, 6);
+
+ assertThat(aList).containsNoneIn(Arrays.asList(9, 10, 11));
+ }
+
+ @Test
+ public void whenCheckingIterable_thenContainsExactElements() {
+ List aList = Arrays.asList("10", "20", "30");
+ List anotherList = Arrays.asList("10", "20", "30");
+
+ assertThat(aList).containsExactlyElementsIn(anotherList)
+ .inOrder();
+ }
+
+ @Test
+ public void whenCheckingIterable_thenOrdered() {
+ Set aSet = new LinkedHashSet<>(Arrays.asList("one", "three", "two"));
+
+ assertThat(aSet).isOrdered();
+ }
+
+ @Test
+ public void givenComparator_whenCheckingIterable_thenOrdered() {
+ Comparator aComparator = (a, b) -> new Float(a).compareTo(new Float(b));
+
+ List aList = Arrays.asList("1", "012", "0020", "100");
+
+ assertThat(aList).isOrdered(aComparator);
+ }
+
+ @Test
+ public void whenCheckingMap_thenContainsEntry() {
+ Map aMap = new HashMap<>();
+ aMap.put("one", 1L);
+
+ assertThat(aMap).containsEntry("one", 1L);
+ }
+
+ @Test
+ public void whenCheckingMap_thenContainsKey() {
+ Map map = new HashMap<>();
+ map.put("one", 1L);
+
+ assertThat(map).containsKey("one");
+ }
+
+ @Test
+ public void whenCheckingMap_thenContainsEntries() {
+ Map aMap = new HashMap<>();
+ aMap.put("first", 1L);
+ aMap.put("second", 2.0);
+ aMap.put("third", 3f);
+
+ Map anotherMap = new HashMap<>(aMap);
+
+ assertThat(aMap).containsExactlyEntriesIn(anotherMap);
+ }
+
+ @Test
+ public void whenCheckingException_thenInstanceOf() {
+ Exception anException = new IllegalArgumentException(new NumberFormatException());
+
+ assertThat(anException).hasCauseThat()
+ .isInstanceOf(NumberFormatException.class);
+ }
+
+ @Test
+ public void whenCheckingException_thenCauseMessageIsKnown() {
+ Exception anException = new IllegalArgumentException("Bad value");
+
+ assertThat(anException).hasMessageThat()
+ .startsWith("Bad");
+ }
+
+ @Test
+ public void whenCheckingClass_thenIsAssignable() {
+ Class aClass = Double.class;
+
+ assertThat(aClass).isAssignableTo(Number.class);
+ }
+
+ // Java 8 Tests
+ @Test
+ public void whenChekingJavaOptional_thenHasValue() {
+ Optional anOptional = Optional.of(1);
+
+ assertThat(anOptional).hasValue(1);
+ }
+
+ @Test
+ public void whenCheckingJavaOptional_thenPresent() {
+ Optional anOptional = Optional.of("Baeldung");
+
+ assertThat(anOptional).isPresent();
+ }
+
+ @Test
+ public void whenCheckingJavaOptional_thenEmpty() {
+ Optional anOptional = Optional.empty();
+
+ assertThat(anOptional).isEmpty();
+ }
+
+ @Test
+ public void whenCheckingStream_thenContainsInOrder() {
+ Stream anStream = Stream.of(1, 2, 3);
+
+ assertThat(anStream).containsAllOf(1, 2, 3)
+ .inOrder();
+ }
+
+ @Test
+ public void whenCheckingStream_thenDoesNotContain() {
+ Stream anStream = IntStream.range(1, 100)
+ .boxed();
+
+ assertThat(anStream).doesNotContain(0);
+ }
+
+ // Guava Tests
+ @Test
+ public void whenChekingGuavaOptional_thenIsAbsent() {
+ com.google.common.base.Optional anOptional = com.google.common.base.Optional.absent();
+
+ assertThat(anOptional).isAbsent();
+ }
+
+ @Test
+ public void whenCheckingGuavaMultimap_thenExpectedSize() {
+ Multimap aMultimap = ArrayListMultimap.create();
+ aMultimap.put("one", 1L);
+ aMultimap.put("one", 2.0);
+
+ assertThat(aMultimap).valuesForKey("one")
+ .hasSize(2);
+ }
+
+ @Test
+ public void whenCheckingGuavaMultiset_thenExpectedCount() {
+ TreeMultiset aMultiset = TreeMultiset.create();
+ aMultiset.add("baeldung", 10);
+
+ assertThat(aMultiset).hasCount("baeldung", 10);
+ }
+
+ @Test
+ public void whenCheckingGuavaTable_thenContains() {
+ Table aTable = getDummyGuavaTable();
+
+ assertThat(aTable).contains("firstRow", "firstColumn");
+ }
+
+ @Test
+ public void whenCheckingGuavaTable_thenContainsCell() {
+ Table aTable = getDummyGuavaTable();
+
+ assertThat(aTable).containsCell("firstRow", "firstColumn", "baeldung");
+ }
+
+ @Test
+ public void whenCheckingGuavaTable_thenContainsRow() {
+ Table aTable = getDummyGuavaTable();
+
+ assertThat(aTable).containsRow("firstRow");
+ }
+
+ @Test
+ public void whenCheckingGuavaTable_thenContainsColumn() {
+ Table aTable = getDummyGuavaTable();
+
+ assertThat(aTable).containsColumn("firstColumn");
+ }
+
+ @Test
+ public void whenCheckingGuavaTable_thenContainsValue() {
+ Table aTable = getDummyGuavaTable();
+
+ assertThat(aTable).containsValue("baeldung");
+ }
+
+ @Ignore
+ @Test
+ public void whenFailingAssertion_thenMessagePrefix() {
+ User aUser = new User();
+
+ assertThat(aUser).named("User [%s]", aUser.getName())
+ .isNull();
+ }
+
+ @Ignore
+ @Test
+ public void whenFailingAssertion_thenCustomMessage() {
+ User aUser = new User();
+
+ assertWithMessage("TEST-985: Secret user subject was NOT null!").that(aUser)
+ .isNull();
+ }
+
+ @Ignore
+ @Test
+ public void whenFailingAssertion_thenCustomMessageAndPrefix() {
+ User aUser = new User();
+
+ assertWithMessage("TEST-985: Secret user subject was NOT null!").that(aUser)
+ .named("User [%s]", aUser.getName())
+ .isNull();
+ }
+
+ private Table getDummyGuavaTable() {
+ Table aTable = TreeBasedTable.create();
+ aTable.put("firstRow", "firstColumn", "baeldung");
+ return aTable;
+ }
+
+ // Custom User type
+ @Test
+ public void whenCheckingUser_thenHasName() {
+ User aUser = new User();
+
+ assertThat(aUser).hasName("John Doe");
+ }
+
+ @Test
+ public void whenCheckingUser_thenHasNameIgnoringCase() {
+ User aUser = new User();
+
+ assertThat(aUser).hasNameIgnoringCase("john doe");
+ }
+
+ @Test
+ public void givenUser_whenCheckingEmails_thenExpectedSize() {
+ User aUser = new User();
+
+ assertThat(aUser).emails()
+ .hasSize(2);
+ }
+
+}