diff --git a/pom.xml b/pom.xml
index d7485e1653..a783412bbf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -798,7 +798,6 @@
assertion-libraries
testing-modules
- testing-modules-2
twilio
twitter4j
@@ -1494,7 +1493,6 @@
assertion-libraries
testing-modules
- testing-modules-2
twilio
twitter4j
diff --git a/testing-modules-2/README.md b/testing-modules-2/README.md
deleted file mode 100644
index 949ae7f760..0000000000
--- a/testing-modules-2/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-## Testing Modules
-
-This is a aggregator module containing several modules focused on testing libraries 2.
-
diff --git a/testing-modules/README.md b/testing-modules/README.md
index d534e5cea6..21fc87a67f 100644
--- a/testing-modules/README.md
+++ b/testing-modules/README.md
@@ -1,5 +1,4 @@
## Testing Modules
-This is a aggregator module containing several modules focused on testing libraries.
-
+This is a aggregator module containing several modules focused on testing libraries.
diff --git a/testing-modules/assertion-libraries/README.md b/testing-modules/assertion-libraries/README.md
new file mode 100644
index 0000000000..d69457fdeb
--- /dev/null
+++ b/testing-modules/assertion-libraries/README.md
@@ -0,0 +1,13 @@
+
+## Relevant Articles
+
+- [AssertJās Java 8 Features](http://www.baeldung.com/assertJ-java-8-features)
+- [AssertJ for Guava](http://www.baeldung.com/assertJ-for-guava)
+- [Introduction to AssertJ](http://www.baeldung.com/introduction-to-assertj)
+- [Testing with Google Truth](http://www.baeldung.com/google-truth)
+- [Testing with JGoTesting](http://www.baeldung.com/jgotesting)
+- [Guide to JSpec](http://www.baeldung.com/jspec)
+- [Custom Assertions with AssertJ](http://www.baeldung.com/assertj-custom-assertion)
+- [Using Conditions with AssertJ Assertions](http://www.baeldung.com/assertj-conditions)
+- [AssertJ Exception Assertions](http://www.baeldung.com/assertj-exception-assertion)
+
diff --git a/testing-modules/assertion-libraries/pom.xml b/testing-modules/assertion-libraries/pom.xml
new file mode 100644
index 0000000000..274806d336
--- /dev/null
+++ b/testing-modules/assertion-libraries/pom.xml
@@ -0,0 +1,81 @@
+
+ 4.0.0
+ com.baeldung
+ assertion-libraries
+ 0.1-SNAPSHOT
+ assertion-libraries
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../parent-java
+
+
+
+
+ com.google.truth
+ truth
+ ${truth.version}
+
+
+ com.google.truth.extensions
+ truth-java8-extension
+ ${truth.version}
+ test
+
+
+ org.assertj
+ assertj-guava
+ ${assertj-guava.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
+
+ org.javalite
+ javalite-common
+ ${javalite.version}
+
+
+ org.jgotesting
+ jgotesting
+ ${jgotesting.version}
+ test
+
+
+
+
+
+
+
+ org.assertj
+ assertj-assertions-generator-maven-plugin
+ ${assertj-generator.version}
+
+
+ com.baeldung.testing.assertj.custom.Person
+
+
+
+
+
+
+
+ 0.32
+ 3.1.0
+ 3.9.0
+ 2.1.0
+ 1.4.13
+ 0.12
+
+
+
+
+
+
+
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Dog.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Dog.java
new file mode 100644
index 0000000000..6c049e1a10
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Dog.java
@@ -0,0 +1,19 @@
+package com.baeldung.assertj;
+
+public class Dog {
+ private String name;
+ private Float weight;
+
+ public Dog(String name, Float weight) {
+ this.name = name;
+ this.weight = weight;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Float getWeight() {
+ return weight;
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Member.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Member.java
new file mode 100644
index 0000000000..baf3c2df52
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Member.java
@@ -0,0 +1,19 @@
+package com.baeldung.assertj;
+
+public class Member {
+ private String name;
+ private int age;
+
+ public Member(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Person.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Person.java
new file mode 100644
index 0000000000..09b16b4f5b
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/Person.java
@@ -0,0 +1,19 @@
+package com.baeldung.assertj;
+
+public class Person {
+ private String name;
+ private Integer age;
+
+ public Person(String name, Integer age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/custom/Person.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/custom/Person.java
new file mode 100644
index 0000000000..5506a56b51
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/assertj/custom/Person.java
@@ -0,0 +1,32 @@
+package com.baeldung.assertj.custom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Person {
+ private String fullName;
+ private int age;
+ private List nicknames;
+
+ public Person(String fullName, int age) {
+ this.fullName = fullName;
+ this.age = age;
+ this.nicknames = new ArrayList<>();
+ }
+
+ public void addNickname(String nickname) {
+ nicknames.add(nickname);
+ }
+
+ public String getFullName() {
+ return fullName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public List getNicknames() {
+ return nicknames;
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Animal.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Animal.java
new file mode 100644
index 0000000000..efb4c62bde
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Animal.java
@@ -0,0 +1,41 @@
+package com.baeldung.jspec;
+
+public abstract class Animal {
+
+ protected String name;
+
+ public Animal(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Animal other = (Animal) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cage.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cage.java
new file mode 100644
index 0000000000..73ea343600
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cage.java
@@ -0,0 +1,48 @@
+package com.baeldung.jspec;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Cage {
+
+ private Set animals = new HashSet<>();
+
+ public void put(Animal animal) {
+ animals.add(animal);
+ }
+
+ public void put(Animal... animals) {
+ this.animals.addAll(Arrays.asList(animals));
+ }
+
+ public Animal release(Animal animal) {
+ return animals.remove(animal) ? animal : null;
+ }
+
+ public void open() {
+ animals.clear();
+ }
+
+ public boolean hasAnimals() {
+ return animals.size() > 0;
+ }
+
+ public boolean isEmpty() {
+ return animals.isEmpty();
+ }
+
+ public Set getAnimals() {
+ return this.animals;
+ }
+
+ public int size() {
+ return animals.size();
+ }
+
+ @Override
+ public String toString() {
+ return "Cage [animals=" + animals + "]";
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cat.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cat.java
new file mode 100644
index 0000000000..5021a1481c
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Cat.java
@@ -0,0 +1,14 @@
+package com.baeldung.jspec;
+
+public class Cat extends Animal {
+
+ public Cat(String name) {
+ super(name);
+ }
+
+ @Override
+ public String toString() {
+ return "Cat [name=" + name + "]";
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Dog.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Dog.java
new file mode 100644
index 0000000000..43626941e3
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/jspec/Dog.java
@@ -0,0 +1,14 @@
+package com.baeldung.jspec;
+
+public class Dog extends Animal {
+
+ public Dog(String name) {
+ super(name);
+ }
+
+ @Override
+ public String toString() {
+ return "Dog [name=" + name + "]";
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/main/java/com/baeldung/truth/User.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/truth/User.java
new file mode 100644
index 0000000000..2b5ffde19f
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/truth/User.java
@@ -0,0 +1,57 @@
+package com.baeldung.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-modules/assertion-libraries/src/main/java/com/baeldung/truth/UserSubject.java b/testing-modules/assertion-libraries/src/main/java/com/baeldung/truth/UserSubject.java
new file mode 100644
index 0000000000..b478043ad8
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/main/java/com/baeldung/truth/UserSubject.java
@@ -0,0 +1,46 @@
+package com.baeldung.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-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java
new file mode 100644
index 0000000000..ec2d93500f
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJConditionUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.assertj;
+
+import static org.assertj.core.api.Assertions.allOf;
+import static org.assertj.core.api.Assertions.anyOf;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.not;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.assertj.core.api.Condition;
+import org.junit.Test;
+
+public class AssertJConditionUnitTest {
+ private Condition senior = new Condition<>(m -> m.getAge() >= 60, "senior");
+ private Condition nameJohn = new Condition<>(m -> m.getName().equalsIgnoreCase("John"), "name John");
+
+ @Test
+ public void whenUsingMemberAgeCondition_thenCorrect() {
+ Member member = new Member("John", 65);
+ assertThat(member).is(senior);
+
+ try {
+ assertThat(member).isNot(senior);
+ fail();
+ } catch (AssertionError e) {
+ assertThat(e).hasMessageContaining("not to be ");
+ }
+ }
+
+ @Test
+ public void whenUsingMemberNameCondition_thenCorrect() {
+ Member member = new Member("Jane", 60);
+ assertThat(member).doesNotHave(nameJohn);
+
+ try {
+ assertThat(member).has(nameJohn);
+ fail();
+ } catch (AssertionError e) {
+ assertThat(e).hasMessageContaining("");
+ }
+ }
+
+ @Test
+ public void whenCollectionConditionsAreSatisfied_thenCorrect() {
+ List members = new ArrayList<>();
+ members.add(new Member("Alice", 50));
+ members.add(new Member("Bob", 60));
+
+ assertThat(members).haveExactly(1, senior);
+ assertThat(members).doNotHave(nameJohn);
+ }
+
+ @Test
+ public void whenCombiningAllOfConditions_thenCorrect() {
+ Member john = new Member("John", 60);
+ Member jane = new Member("Jane", 50);
+
+ assertThat(john).is(allOf(senior, nameJohn));
+ assertThat(jane).is(allOf(not(nameJohn), not(senior)));
+ }
+
+ @Test
+ public void whenCombiningAnyOfConditions_thenCorrect() {
+ Member john = new Member("John", 50);
+ Member jane = new Member("Jane", 60);
+
+ assertThat(john).is(anyOf(senior, nameJohn));
+ assertThat(jane).is(anyOf(nameJohn, senior));
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJCoreUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJCoreUnitTest.java
new file mode 100644
index 0000000000..73b9b373a1
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJCoreUnitTest.java
@@ -0,0 +1,117 @@
+package com.baeldung.assertj;
+
+import org.assertj.core.util.Maps;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import static org.assertj.core.api.Assertions.*;
+
+public class AssertJCoreUnitTest {
+
+ @Test
+ public void whenComparingReferences_thenNotEqual() throws Exception {
+ Dog fido = new Dog("Fido", 5.15f);
+ Dog fidosClone = new Dog("Fido", 5.15f);
+
+ assertThat(fido).isNotEqualTo(fidosClone);
+ }
+
+ @Test
+ public void whenComparingFields_thenEqual() throws Exception {
+ Dog fido = new Dog("Fido", 5.15f);
+ Dog fidosClone = new Dog("Fido", 5.15f);
+
+ assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);
+ }
+
+ @Test
+ public void whenCheckingForElement_thenContains() throws Exception {
+ List list = Arrays.asList("1", "2", "3");
+
+ assertThat(list).contains("1");
+ }
+
+ @Test
+ public void whenCheckingForElement_thenMultipleAssertions() throws Exception {
+ List list = Arrays.asList("1", "2", "3");
+
+ assertThat(list).isNotEmpty();
+ assertThat(list).startsWith("1");
+ assertThat(list).doesNotContainNull();
+
+ assertThat(list).isNotEmpty().contains("1").startsWith("1").doesNotContainNull().containsSequence("2", "3");
+ }
+
+ @Test
+ public void whenCheckingRunnable_thenIsInterface() throws Exception {
+ assertThat(Runnable.class).isInterface();
+ }
+
+ @Test
+ public void whenCheckingCharacter_thenIsUnicode() throws Exception {
+ char someCharacter = 'c';
+
+ assertThat(someCharacter).isNotEqualTo('a').inUnicode().isGreaterThanOrEqualTo('b').isLowerCase();
+ }
+
+ @Test
+ public void whenAssigningNSEExToException_thenIsAssignable() throws Exception {
+ assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);
+ }
+
+ @Test
+ public void whenComparingWithOffset_thenEquals() throws Exception {
+ assertThat(5.1).isEqualTo(5, withPrecision(1d));
+ }
+
+ @Test
+ public void whenCheckingString_then() throws Exception {
+ assertThat("".isEmpty()).isTrue();
+ }
+
+ @Test
+ public void whenCheckingFile_then() throws Exception {
+ final File someFile = File.createTempFile("aaa", "bbb");
+ someFile.deleteOnExit();
+
+ assertThat(someFile).exists().isFile().canRead().canWrite();
+ }
+
+ @Test
+ public void whenCheckingIS_then() throws Exception {
+ InputStream given = new ByteArrayInputStream("foo".getBytes());
+ InputStream expected = new ByteArrayInputStream("foo".getBytes());
+
+ assertThat(given).hasSameContentAs(expected);
+ }
+
+ @Test
+ public void whenGivenMap_then() throws Exception {
+ Map map = Maps.newHashMap(2, "a");
+
+ assertThat(map).isNotEmpty().containsKey(2).doesNotContainKeys(10).contains(entry(2, "a"));
+ }
+
+ @Test
+ public void whenGivenException_then() throws Exception {
+ Exception ex = new Exception("abc");
+
+ assertThat(ex).hasNoCause().hasMessageEndingWith("c");
+ }
+
+ @Ignore // IN ORDER TO TEST, REMOVE THIS LINE
+ @Test
+ public void whenRunningAssertion_thenDescribed() throws Exception {
+ Person person = new Person("Alex", 34);
+
+ assertThat(person.getAge()).as("%s's age should be equal to 100").isEqualTo(100);
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJGuavaUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJGuavaUnitTest.java
new file mode 100644
index 0000000000..6a552aee78
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJGuavaUnitTest.java
@@ -0,0 +1,96 @@
+package com.baeldung.assertj;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.Range;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeRangeMap;
+import com.google.common.io.Files;
+import org.assertj.guava.data.MapEntry;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.entry;
+
+public class AssertJGuavaUnitTest {
+
+ @Test
+ public void givenTwoEmptyFiles_whenComparingContent_thenEqual() throws Exception {
+ final File temp1 = File.createTempFile("bael", "dung1");
+ final File temp2 = File.createTempFile("bael", "dung2");
+
+ assertThat(Files.asByteSource(temp1)).hasSize(0).hasSameContentAs(Files.asByteSource(temp2));
+ }
+
+ @Test
+ public void givenMultimap_whenVerifying_thenCorrect() throws Exception {
+ final Multimap mmap = ArrayListMultimap.create();
+ mmap.put(1, "one");
+ mmap.put(1, "1");
+
+ assertThat(mmap).hasSize(2).containsKeys(1).contains(entry(1, "one")).contains(entry(1, "1"));
+ }
+
+ @Test
+ public void givenMultimaps_whenVerifyingContent_thenCorrect() throws Exception {
+ final Multimap mmap1 = ArrayListMultimap.create();
+ mmap1.put(1, "one");
+ mmap1.put(1, "1");
+ mmap1.put(2, "two");
+ mmap1.put(2, "2");
+
+ final Multimap mmap1_clone = Multimaps.newSetMultimap(new HashMap<>(), HashSet::new);
+ mmap1_clone.put(1, "one");
+ mmap1_clone.put(1, "1");
+ mmap1_clone.put(2, "two");
+ mmap1_clone.put(2, "2");
+
+ final Multimap mmap2 = Multimaps.newSetMultimap(new HashMap<>(), HashSet::new);
+ mmap2.put(1, "one");
+ mmap2.put(1, "1");
+
+ assertThat(mmap1).containsAllEntriesOf(mmap2).containsAllEntriesOf(mmap1_clone).hasSameEntriesAs(mmap1_clone);
+ }
+
+ @Test
+ public void givenOptional_whenVerifyingContent_thenShouldBeEqual() throws Exception {
+ final Optional something = Optional.of("something");
+
+ assertThat(something).isPresent().extractingValue().isEqualTo("something");
+ }
+
+ @Test
+ public void givenRange_whenVerifying_thenShouldBeCorrect() throws Exception {
+ final Range range = Range.openClosed("a", "g");
+
+ assertThat(range).hasOpenedLowerBound().isNotEmpty().hasClosedUpperBound().contains("b");
+ }
+
+ @Test
+ public void givenRangeMap_whenVerifying_thenShouldBeCorrect() throws Exception {
+ final TreeRangeMap map = TreeRangeMap.create();
+
+ map.put(Range.closed(0, 60), "F");
+ map.put(Range.closed(61, 70), "D");
+
+ assertThat(map).isNotEmpty().containsKeys(0).contains(MapEntry.entry(34, "F"));
+ }
+
+ @Test
+ public void givenTable_whenVerifying_thenShouldBeCorrect() throws Exception {
+ final Table table = HashBasedTable.create(2, 2);
+
+ table.put(1, "A", "PRESENT");
+ table.put(1, "B", "ABSENT");
+
+ assertThat(table).hasRowCount(1).containsValues("ABSENT").containsCell(1, "B", "ABSENT");
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJJava8UnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJJava8UnitTest.java
new file mode 100644
index 0000000000..a2f58d677d
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/AssertJJava8UnitTest.java
@@ -0,0 +1,108 @@
+package com.baeldung.assertj;
+
+import org.junit.Test;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import static java.time.LocalDate.ofYearDay;
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AssertJJava8UnitTest {
+
+ @Test
+ public void givenOptional_shouldAssert() throws Exception {
+ final Optional givenOptional = Optional.of("something");
+
+ assertThat(givenOptional).isPresent().hasValue("something");
+ }
+
+ @Test
+ public void givenPredicate_shouldAssert() throws Exception {
+ final Predicate predicate = s -> s.length() > 4;
+
+ assertThat(predicate).accepts("aaaaa", "bbbbb").rejects("a", "b").acceptsAll(asList("aaaaa", "bbbbb")).rejectsAll(asList("a", "b"));
+ }
+
+ @Test
+ public void givenLocalDate_shouldAssert() throws Exception {
+ final LocalDate givenLocalDate = LocalDate.of(2016, 7, 8);
+ final LocalDate todayDate = LocalDate.now();
+
+ assertThat(givenLocalDate).isBefore(LocalDate.of(2020, 7, 8)).isAfterOrEqualTo(LocalDate.of(1989, 7, 8));
+
+ assertThat(todayDate).isAfter(LocalDate.of(1989, 7, 8)).isToday();
+ }
+
+ @Test
+ public void givenLocalDateTime_shouldAssert() throws Exception {
+ final LocalDateTime givenLocalDate = LocalDateTime.of(2016, 7, 8, 12, 0);
+
+ assertThat(givenLocalDate).isBefore(LocalDateTime.of(2020, 7, 8, 11, 2));
+ }
+
+ @Test
+ public void givenLocalTime_shouldAssert() throws Exception {
+ final LocalTime givenLocalTime = LocalTime.of(12, 15);
+
+ assertThat(givenLocalTime).isAfter(LocalTime.of(1, 0)).hasSameHourAs(LocalTime.of(12, 0));
+ }
+
+ @Test
+ public void givenList_shouldAssertFlatExtracting() throws Exception {
+ final List givenList = asList(ofYearDay(2016, 5), ofYearDay(2015, 6));
+
+ assertThat(givenList).flatExtracting(LocalDate::getYear).contains(2015);
+ }
+
+ @Test
+ public void givenList_shouldAssertFlatExtractingLeapYear() throws Exception {
+ final List givenList = asList(ofYearDay(2016, 5), ofYearDay(2015, 6));
+
+ assertThat(givenList).flatExtracting(LocalDate::isLeapYear).contains(true);
+ }
+
+ @Test
+ public void givenList_shouldAssertFlatExtractingClass() throws Exception {
+ final List givenList = asList(ofYearDay(2016, 5), ofYearDay(2015, 6));
+
+ assertThat(givenList).flatExtracting(Object::getClass).contains(LocalDate.class);
+ }
+
+ @Test
+ public void givenList_shouldAssertMultipleFlatExtracting() throws Exception {
+ final List givenList = asList(ofYearDay(2016, 5), ofYearDay(2015, 6));
+
+ assertThat(givenList).flatExtracting(LocalDate::getYear, LocalDate::getDayOfMonth).contains(2015, 6);
+ }
+
+ @Test
+ public void givenString_shouldSatisfy() throws Exception {
+ final String givenString = "someString";
+
+ assertThat(givenString).satisfies(s -> {
+ assertThat(s).isNotEmpty();
+ assertThat(s).hasSize(10);
+ });
+ }
+
+ @Test
+ public void givenString_shouldMatch() throws Exception {
+ final String emptyString = "";
+
+ assertThat(emptyString).matches(String::isEmpty);
+ }
+
+ @Test
+ public void givenList_shouldHasOnlyOneElementSatisfying() throws Exception {
+ final List givenList = Arrays.asList("");
+
+ assertThat(givenList).hasOnlyOneElementSatisfying(s -> assertThat(s).isEmpty());
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/AssertJCustomAssertionsUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/AssertJCustomAssertionsUnitTest.java
new file mode 100644
index 0000000000..98f50568a8
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/AssertJCustomAssertionsUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.assertj.custom;
+
+import static com.baeldung.assertj.custom.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class AssertJCustomAssertionsUnitTest {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void whenPersonNameMatches_thenCorrect() {
+ Person person = new Person("John Doe", 20);
+ assertThat(person).hasFullName("John Doe");
+ }
+
+ @Test
+ public void whenPersonAgeLessThanEighteen_thenNotAdult() {
+ Person person = new Person("Jane Roe", 16);
+
+ try {
+ assertThat(person).isAdult();
+ fail();
+ } catch (AssertionError e) {
+ org.assertj.core.api.Assertions.assertThat(e).hasMessage("Expected person to be adult");
+ }
+ }
+
+ @Test
+ public void whenPersonDoesNotHaveAMatchingNickname_thenIncorrect() {
+ Person person = new Person("John Doe", 20);
+ person.addNickname("Nick");
+
+ try {
+ assertThat(person).hasNickname("John");
+ fail();
+ } catch (AssertionError e) {
+ org.assertj.core.api.Assertions.assertThat(e).hasMessage("Expected person to have nickname John");
+ }
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/Assertions.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/Assertions.java
new file mode 100644
index 0000000000..3e1021851e
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/Assertions.java
@@ -0,0 +1,9 @@
+package com.baeldung.assertj.custom;
+
+public class Assertions {
+ public static PersonAssert assertThat(Person actual) {
+ return new PersonAssert(actual);
+ }
+
+ // static factory methods of other assertion classes
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/PersonAssert.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/PersonAssert.java
new file mode 100644
index 0000000000..5be093644a
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/custom/PersonAssert.java
@@ -0,0 +1,38 @@
+package com.baeldung.assertj.custom;
+
+import org.assertj.core.api.AbstractAssert;
+
+public class PersonAssert extends AbstractAssert {
+
+ public PersonAssert(Person actual) {
+ super(actual, PersonAssert.class);
+ }
+
+ public static PersonAssert assertThat(Person actual) {
+ return new PersonAssert(actual);
+ }
+
+ public PersonAssert hasFullName(String fullName) {
+ isNotNull();
+ if (!actual.getFullName().equals(fullName)) {
+ failWithMessage("Expected person to have full name %s but was %s", fullName, actual.getFullName());
+ }
+ return this;
+ }
+
+ public PersonAssert isAdult() {
+ isNotNull();
+ if (actual.getAge() < 18) {
+ failWithMessage("Expected person to be adult");
+ }
+ return this;
+ }
+
+ public PersonAssert hasNickname(String nickName) {
+ isNotNull();
+ if (!actual.getNicknames().contains(nickName)) {
+ failWithMessage("Expected person to have nickname %s", nickName);
+ }
+ return this;
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java7StyleAssertions.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java7StyleAssertions.java
new file mode 100644
index 0000000000..ab93f8eac7
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java7StyleAssertions.java
@@ -0,0 +1,24 @@
+package com.baeldung.assertj.exceptions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+
+import org.junit.Test;
+
+public class Java7StyleAssertions {
+
+ @Test
+ public void whenDividingByZero_thenArithmeticException() {
+ try {
+ int numerator = 10;
+ int denominator = 0;
+ int quotient = numerator / denominator;
+ fail("ArithmeticException expected because dividing by zero yields an ArithmeticException.");
+ failBecauseExceptionWasNotThrown(ArithmeticException.class);
+ } catch (Exception e) {
+ assertThat(e).hasMessage("/ by zero");
+ assertThat(e).isInstanceOf(ArithmeticException.class);
+ }
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java8StyleAssertions.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java8StyleAssertions.java
new file mode 100644
index 0000000000..4d4e2aedfc
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/assertj/exceptions/Java8StyleAssertions.java
@@ -0,0 +1,66 @@
+package com.baeldung.assertj.exceptions;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.catchThrowable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.Test;
+
+public class Java8StyleAssertions {
+
+ @Test
+ public void whenGettingOutOfBoundsItem_thenIndexOutOfBoundsException() {
+ assertThatThrownBy(() -> {
+ ArrayList myStringList = new ArrayList(Arrays.asList("Strine one", "String two"));
+ myStringList.get(2);
+ }).isInstanceOf(IndexOutOfBoundsException.class)
+ .hasMessageStartingWith("Index: 2")
+ .hasMessageContaining("2")
+ .hasMessageEndingWith("Size: 2")
+ .hasMessageContaining("Index: 2, Size: 2")
+ .hasMessage("Index: %s, Size: %s", 2, 2)
+ .hasMessageMatching("Index: \\d+, Size: \\d+")
+ .hasNoCause();
+ }
+
+ @Test
+ public void whenWrappingException_thenCauseInstanceOfWrappedExceptionType() {
+ assertThatThrownBy(() -> {
+ try {
+ throw new IOException();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }).isInstanceOf(RuntimeException.class)
+ .hasCauseInstanceOf(IOException.class)
+ .hasStackTraceContaining("IOException");
+ }
+
+ @Test
+ public void whenDividingByZero_thenArithmeticException() {
+ assertThatExceptionOfType(ArithmeticException.class).isThrownBy(() -> {
+ int numerator = 10;
+ int denominator = 0;
+ int quotient = numerator / denominator;
+ })
+ .withMessageContaining("/ by zero");
+
+ // Alternatively:
+
+ // when
+ Throwable thrown = catchThrowable(() -> {
+ int numerator = 10;
+ int denominator = 0;
+ int quotient = numerator / denominator;
+ });
+
+ // then
+ assertThat(thrown).isInstanceOf(ArithmeticException.class)
+ .hasMessageContaining("/ by zero");
+
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/jgotesting/JGoTestingUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jgotesting/JGoTestingUnitTest.java
new file mode 100644
index 0000000000..650fb3e5c5
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jgotesting/JGoTestingUnitTest.java
@@ -0,0 +1,93 @@
+package com.baeldung.testing.jgotesting;
+
+import java.io.File;
+import static org.hamcrest.Matchers.equalToIgnoringCase;
+import static org.hamcrest.Matchers.is;
+import org.jgotesting.rule.JGoTestRule;
+import static org.jgotesting.Assert.*; // same methods as org.junit.Assert.*
+import static org.jgotesting.Check.*; // ditto, with different names
+import static org.jgotesting.Testing.*;
+import org.jgotesting.Checker;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class JGoTestingUnitTest {
+ @Rule
+ public final JGoTestRule test = new JGoTestRule();
+
+ @Test
+ public void whenComparingIntegers_thenEqual() {
+ int anInt = 10;
+
+ assertEquals(anInt, 10);
+ checkEquals(anInt, 10);
+ }
+
+ @Ignore
+ @Test
+ public void whenComparingNumbers_thenLoggedMessage() {
+ log("There was something wrong when comparing numbers");
+
+ int anInt = 10;
+ int anotherInt = 10;
+
+ checkEquals(anInt, 10);
+ checkTrue("First number should be bigger", 10 > anotherInt);
+ checkSame(anInt, anotherInt);
+ }
+
+ @Ignore
+ @Test
+ public void whenComparingNumbers_thenFormattedMessage() {
+ int anInt = 10;
+ int anotherInt = 10;
+
+ logf("There was something wrong when comparing numbers %d and %d", anInt, anotherInt);
+
+ checkEquals(anInt, 10);
+ checkTrue("First number should be bigger", 10 > anotherInt);
+ checkSame(anInt, anotherInt);
+ }
+
+ @Test
+ public void whenComparingStrings_thenMultipleAssertions() {
+ String aString = "This is a string";
+ String anotherString = "This Is A String";
+
+ test.check(aString, equalToIgnoringCase(anotherString))
+ .check(aString.length() == 16)
+ .check(aString.startsWith("This"));
+ }
+
+ @Ignore
+ @Test
+ public void whenComparingStrings_thenMultipleFailingAssertions() {
+ String aString = "the test string";
+ String anotherString = "The Test String";
+
+ checkEquals("Strings are not equal!", aString, anotherString);
+ checkTrue("String is longer than one character", aString.length() == 1);
+ checkSame("Strings are not the same", aString, anotherString);
+ }
+
+ @Ignore
+ @Test
+ public void givenFile_whenDoesnotExists_thenTerminated() throws Exception {
+ File aFile = new File("a_dummy_file.txt");
+ terminateIf(aFile.exists(), is(false));
+
+ // This doesn't get executed
+ checkEquals(aFile.getName(), "a_dummy_file.txt");
+ }
+
+ @Test
+ public void givenChecker_whenComparingStrings_thenEqual() throws Exception {
+ Checker aChecker = s -> s.matches("\\d+");
+
+ String aString = "1235";
+ test.check(aString, aChecker);
+ }
+
+}
+
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/CageUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/CageUnitTest.java
new file mode 100644
index 0000000000..33ef986588
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/CageUnitTest.java
@@ -0,0 +1,126 @@
+package com.baeldung.jspec;
+
+import static org.javalite.test.jspec.JSpec.$;
+import static org.javalite.test.jspec.JSpec.expect;
+import static org.javalite.test.jspec.JSpec.the;
+
+import java.util.Set;
+
+import org.javalite.test.jspec.DifferenceExpectation;
+import org.junit.Test;
+
+public class CageUnitTest {
+
+ Cat tomCat = new Cat("Tom");
+ Cat felixCat = new Cat("Felix");
+ Dog boltDog = new Dog("Bolt");
+ Cage cage = new Cage();
+
+
+ @Test
+ public void puttingAnimals_shouldIncreaseCageSize() {
+ // When
+ cage.put(tomCat, boltDog);
+
+ // Then
+ the(cage.size()).shouldEqual(2);
+ }
+
+ @Test
+ public void releasingAnimals_shouldDecreaseCageSize() {
+ // When
+ cage.put(tomCat, boltDog);
+ cage.release(tomCat);
+
+ // Then
+ the(cage.size()).shouldEqual(1);
+ }
+
+ @Test
+ public void puttingAnimals_shouldLeaveThemInsideTheCage() {
+ // When
+ cage.put(tomCat, boltDog);
+
+ // Then
+ the(cage).shouldHave("animals");
+ }
+
+ @Test
+ public void openingTheCage_shouldReleaseAllAnimals() {
+ // When
+ cage.put(tomCat, boltDog);
+
+ // Then
+ the(cage).shouldNotBe("empty");
+
+ // When
+ cage.open();
+
+ // Then
+ the(cage).shouldBe("empty");
+ the(cage.isEmpty()).shouldBeTrue();
+ }
+
+ @Test
+ public void comparingTwoDogs() {
+ // When
+ Dog firstDog = new Dog("Rex");
+ Dog secondDog = new Dog("Rex");
+
+ // Then
+ $(firstDog).shouldEqual(secondDog);
+ $(firstDog).shouldNotBeTheSameAs(secondDog);
+ }
+
+ @Test
+ public void puttingCatsOnly_shouldLetCageAnimalsToContainCats() {
+ // When
+ cage.put(tomCat, felixCat);
+
+ // Then
+ Set animals = cage.getAnimals();
+ the(animals).shouldContain(tomCat);
+ the(animals).shouldContain(felixCat);
+ the(animals).shouldNotContain(boltDog);
+ }
+
+ @Test
+ public void puttingCatsOnly_shouldLetCageToContainCats() {
+ // When
+ cage.put(tomCat, felixCat);
+
+ // Then
+ // Check with toString of the tested objects
+ the(cage).shouldContain(tomCat);
+ the(cage).shouldContain(felixCat);
+ the(cage).shouldNotContain(boltDog);
+ }
+
+ @Test
+ public void puttingMoreAnimals_shouldChangeSize() {
+ // When
+ cage.put(tomCat, boltDog);
+
+ // Then
+ expect( new DifferenceExpectation(cage.size()) {
+
+ @Override
+ public Integer exec() {
+ cage.release(tomCat);
+ return cage.size();
+ }
+ } );
+ }
+
+
+ @Test
+ public void releasingTheDog_shouldReleaseAnAnimalOfDogType() {
+ // When
+ cage.put(boltDog);
+ Animal releasedAnimal = cage.release(boltDog);
+
+ // Then
+ the(releasedAnimal).shouldNotBeNull();
+ the(releasedAnimal).shouldBeA(Dog.class);
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/JSpecUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/JSpecUnitTest.java
new file mode 100644
index 0000000000..0e35e26728
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/jspec/JSpecUnitTest.java
@@ -0,0 +1,57 @@
+package com.baeldung.jspec;
+
+import static org.javalite.test.jspec.JSpec.$;
+import static org.javalite.test.jspec.JSpec.a;
+import static org.javalite.test.jspec.JSpec.expect;
+import static org.javalite.test.jspec.JSpec.it;
+import static org.javalite.test.jspec.JSpec.the;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.javalite.test.jspec.ExceptionExpectation;
+import org.junit.Test;
+
+public class JSpecUnitTest {
+
+ @Test
+ public void onePlusTwo_shouldEqualThree() {
+ $(1 + 2).shouldEqual(3);
+ a(1 + 2).shouldEqual(3);
+ the(1 + 2).shouldEqual(3);
+ it(1 + 2).shouldEqual(3);
+ }
+
+ @Test
+ public void messageShouldContainJSpec() {
+ String message = "Welcome to JSpec demo";
+ // The message should not be empty
+ the(message).shouldNotBe("empty");
+ // The message should contain JSpec
+ the(message).shouldContain("JSpec");
+ }
+
+ public void colorsListShouldContainRed() {
+ List colorsList = Arrays.asList("red", "green", "blue");
+ $(colorsList).shouldContain("red");
+ }
+
+ public void guessedNumberShouldEqualHiddenNumber() {
+ Integer guessedNumber = 11;
+ Integer hiddenNumber = 11;
+
+ $(guessedNumber).shouldEqual(hiddenNumber);
+ $(guessedNumber).shouldNotBeTheSameAs(hiddenNumber);
+ }
+
+ @Test
+ public void dividingByThero_shouldThrowArithmeticException() {
+ expect(new ExceptionExpectation(ArithmeticException.class) {
+ @Override
+ public void exec() throws ArithmeticException {
+ System.out.println(1 / 0);
+ }
+ } );
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AdditionUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AdditionUnitTest.java
new file mode 100644
index 0000000000..ae6fa355fa
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AdditionUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class AdditionUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void testAddition() {
+ assertEquals("addition", 8, calculator.add(5, 3));
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AssertionsUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
new file mode 100644
index 0000000000..b0209b01aa
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
@@ -0,0 +1,101 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.hamcrest.core.IsCollectionContaining.hasItems;
+import static org.junit.Assert.*;
+
+/**
+ * Unit test that demonstrate the different assertions available within JUnit 4
+ */
+public class AssertionsUnitTest {
+
+ @Test
+ public void whenAssertingEquality_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingEqualityWithMessage_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals("failure - strings are not equal", expected, actual);
+ }
+
+ @Test
+ public void whenAssertingArraysEquality_thenEqual() {
+ char[] expected = { 'J', 'u', 'n', 'i', 't' };
+ char[] actual = "Junit".toCharArray();
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void givenNullArrays_whenAssertingArraysEquality_thenEqual() {
+ int[] expected = null;
+ int[] actual = null;
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingNull_thenTrue() {
+ Object car = null;
+
+ assertNull("The car should be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotNull_thenTrue() {
+ Object car = new Object();
+
+ assertNotNull("The car should not be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotSameObject_thenDifferent() {
+ Object cat = new Object();
+ Object dog = new Object();
+
+ assertNotSame(cat, dog);
+ }
+
+ @Test
+ public void whenAssertingSameObject_thenSame() {
+ Object cat = new Object();
+
+ assertSame(cat, cat);
+ }
+
+ @Test
+ public void whenAssertingConditions_thenVerified() {
+ assertTrue("5 is greater then 4", 5 > 4);
+ assertFalse("5 is not greater then 6", 5 > 6);
+ }
+
+ @Test
+ public void when_thenNotFailed() {
+ try {
+ methodThatShouldThrowException();
+ fail("Exception not thrown");
+ } catch (UnsupportedOperationException e) {
+ assertEquals("Operation Not Supported", e.getMessage());
+ }
+ }
+
+ private void methodThatShouldThrowException() {
+ throw new UnsupportedOperationException("Operation Not Supported");
+ }
+
+ @Test
+ public void testAssertThatHasItems() {
+ assertThat(Arrays.asList("Java", "Kotlin", "Scala"), hasItems("Java", "Kotlin"));
+ }
+
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/BlockingTestRunner.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/BlockingTestRunner.java
new file mode 100644
index 0000000000..432d5cda83
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/BlockingTestRunner.java
@@ -0,0 +1,18 @@
+package com.baeldung.junit;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+public class BlockingTestRunner extends BlockJUnit4ClassRunner {
+ public BlockingTestRunner(Class> klass) throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ protected Statement methodInvoker(FrameworkMethod method, Object test) {
+ System.out.println("invoking: " + method.getName());
+ return super.methodInvoker(method, test);
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/CalculatorUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/CalculatorUnitTest.java
new file mode 100644
index 0000000000..d5ca847106
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/CalculatorUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(JUnit4.class)
+public class CalculatorUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void testAddition() {
+ assertEquals("addition", 8, calculator.add(5, 3));
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SubstractionUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SubstractionUnitTest.java
new file mode 100644
index 0000000000..fd98395ebc
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SubstractionUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SubstractionUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void substraction() {
+ assertEquals("substraction", 2, calculator.sub(5, 3));
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SuiteUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SuiteUnitTest.java
new file mode 100644
index 0000000000..76d19f84b2
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/SuiteUnitTest.java
@@ -0,0 +1,12 @@
+package com.baeldung.junit;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AdditionUnitTest.class,
+ SubstractionUnitTest.class})
+public class SuiteUnitTest {
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/TestRunner.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/TestRunner.java
new file mode 100644
index 0000000000..9eb4b3141b
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/junit/TestRunner.java
@@ -0,0 +1,41 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+import java.lang.reflect.Method;
+
+public class TestRunner extends Runner {
+
+ private Class testClass;
+ public TestRunner(Class testClass) {
+ super();
+ this.testClass = testClass;
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.createTestDescription(testClass, "My runner description");
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ System.out.println("running the tests from MyRunner: " + testClass);
+ try {
+ Object testObject = testClass.newInstance();
+ for (Method method : testClass.getMethods()) {
+ if (method.isAnnotationPresent(Test.class)) {
+ notifier.fireTestStarted(Description
+ .createTestDescription(testClass, method.getName()));
+ method.invoke(testObject);
+ notifier.fireTestFinished(Description
+ .createTestDescription(testClass, method.getName()));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/testing-modules/assertion-libraries/src/test/java/com/baeldung/truth/GoogleTruthUnitTest.java b/testing-modules/assertion-libraries/src/test/java/com/baeldung/truth/GoogleTruthUnitTest.java
new file mode 100644
index 0000000000..b7919a29ca
--- /dev/null
+++ b/testing-modules/assertion-libraries/src/test/java/com/baeldung/truth/GoogleTruthUnitTest.java
@@ -0,0 +1,561 @@
+package com.baeldung.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.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 whenCheckingBoolean_thenTrue() {
+ boolean aBoolean = true;
+
+ assertThat(aBoolean).isTrue();
+ }
+
+ @Test
+ public void whenCheckingBoolean_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 whenCheckingString_thenStartsWithString() {
+ String aString = "This is a string";
+
+ assertThat(aString).startsWith("This");
+ }
+
+ @Test
+ public void whenCheckingString_thenContainsString() {
+ String aString = "This is a string";
+
+ assertThat(aString).contains("is a");
+ }
+
+ @Test
+ public void whenCheckingString_thenEndsWithString() {
+ String aString = "This is a string";
+
+ assertThat(aString).endsWith("string");
+ }
+
+ @Test
+ public void whenCheckingString_thenExpectedLength() {
+ String aString = "This is a string";
+
+ assertThat(aString).hasLength(16);
+ }
+
+ @Test
+ public void whenCheckingString_thenEmpty() {
+ String aString = "";
+
+ assertThat(aString).isEmpty();
+ }
+
+ @Test
+ public void whenCheckingString_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 whenCheckingJavaOptional_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 whenCheckingGuavaOptional_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);
+ }
+
+}
diff --git a/testing-modules/junit-4/README.md b/testing-modules/junit-4/README.md
index 4d4588912b..dd975daf58 100644
--- a/testing-modules/junit-4/README.md
+++ b/testing-modules/junit-4/README.md
@@ -1,3 +1,5 @@
### Relevant Articles
- [Guide to JUnit 4 Rules](https://www.baeldung.com/junit-4-rules)
+- [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners)
+- [Introduction to JUnitParams](http://www.baeldung.com/junit-params)
diff --git a/testing-modules/junit-4/src/main/java/com/baeldung/junit/Calculator.java b/testing-modules/junit-4/src/main/java/com/baeldung/junit/Calculator.java
new file mode 100644
index 0000000000..8ea7b3ed1f
--- /dev/null
+++ b/testing-modules/junit-4/src/main/java/com/baeldung/junit/Calculator.java
@@ -0,0 +1,11 @@
+package com.baeldung.junit;
+
+public class Calculator {
+ public int add(int a, int b) {
+ return a + b;
+ }
+
+ public int sub(int a, int b) {
+ return a - b;
+ }
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/AdditionUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/AdditionUnitTest.java
new file mode 100644
index 0000000000..ae6fa355fa
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/AdditionUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class AdditionUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void testAddition() {
+ assertEquals("addition", 8, calculator.add(5, 3));
+ }
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/AssertionsUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
new file mode 100644
index 0000000000..b0209b01aa
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
@@ -0,0 +1,101 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.hamcrest.core.IsCollectionContaining.hasItems;
+import static org.junit.Assert.*;
+
+/**
+ * Unit test that demonstrate the different assertions available within JUnit 4
+ */
+public class AssertionsUnitTest {
+
+ @Test
+ public void whenAssertingEquality_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingEqualityWithMessage_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals("failure - strings are not equal", expected, actual);
+ }
+
+ @Test
+ public void whenAssertingArraysEquality_thenEqual() {
+ char[] expected = { 'J', 'u', 'n', 'i', 't' };
+ char[] actual = "Junit".toCharArray();
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void givenNullArrays_whenAssertingArraysEquality_thenEqual() {
+ int[] expected = null;
+ int[] actual = null;
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingNull_thenTrue() {
+ Object car = null;
+
+ assertNull("The car should be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotNull_thenTrue() {
+ Object car = new Object();
+
+ assertNotNull("The car should not be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotSameObject_thenDifferent() {
+ Object cat = new Object();
+ Object dog = new Object();
+
+ assertNotSame(cat, dog);
+ }
+
+ @Test
+ public void whenAssertingSameObject_thenSame() {
+ Object cat = new Object();
+
+ assertSame(cat, cat);
+ }
+
+ @Test
+ public void whenAssertingConditions_thenVerified() {
+ assertTrue("5 is greater then 4", 5 > 4);
+ assertFalse("5 is not greater then 6", 5 > 6);
+ }
+
+ @Test
+ public void when_thenNotFailed() {
+ try {
+ methodThatShouldThrowException();
+ fail("Exception not thrown");
+ } catch (UnsupportedOperationException e) {
+ assertEquals("Operation Not Supported", e.getMessage());
+ }
+ }
+
+ private void methodThatShouldThrowException() {
+ throw new UnsupportedOperationException("Operation Not Supported");
+ }
+
+ @Test
+ public void testAssertThatHasItems() {
+ assertThat(Arrays.asList("Java", "Kotlin", "Scala"), hasItems("Java", "Kotlin"));
+ }
+
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/BlockingTestRunner.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/BlockingTestRunner.java
new file mode 100644
index 0000000000..432d5cda83
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/BlockingTestRunner.java
@@ -0,0 +1,18 @@
+package com.baeldung.junit;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+public class BlockingTestRunner extends BlockJUnit4ClassRunner {
+ public BlockingTestRunner(Class> klass) throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ protected Statement methodInvoker(FrameworkMethod method, Object test) {
+ System.out.println("invoking: " + method.getName());
+ return super.methodInvoker(method, test);
+ }
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/CalculatorUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/CalculatorUnitTest.java
new file mode 100644
index 0000000000..d5ca847106
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/CalculatorUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(JUnit4.class)
+public class CalculatorUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void testAddition() {
+ assertEquals("addition", 8, calculator.add(5, 3));
+ }
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/SubstractionUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SubstractionUnitTest.java
new file mode 100644
index 0000000000..fd98395ebc
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SubstractionUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SubstractionUnitTest {
+ Calculator calculator = new Calculator();
+
+ @Test
+ public void substraction() {
+ assertEquals("substraction", 2, calculator.sub(5, 3));
+ }
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/SuiteUnitTest.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SuiteUnitTest.java
new file mode 100644
index 0000000000..76d19f84b2
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/SuiteUnitTest.java
@@ -0,0 +1,12 @@
+package com.baeldung.junit;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AdditionUnitTest.class,
+ SubstractionUnitTest.class})
+public class SuiteUnitTest {
+}
diff --git a/testing-modules/junit-4/src/test/java/com/baeldung/junit/TestRunner.java b/testing-modules/junit-4/src/test/java/com/baeldung/junit/TestRunner.java
new file mode 100644
index 0000000000..9eb4b3141b
--- /dev/null
+++ b/testing-modules/junit-4/src/test/java/com/baeldung/junit/TestRunner.java
@@ -0,0 +1,41 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+import java.lang.reflect.Method;
+
+public class TestRunner extends Runner {
+
+ private Class testClass;
+ public TestRunner(Class testClass) {
+ super();
+ this.testClass = testClass;
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.createTestDescription(testClass, "My runner description");
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ System.out.println("running the tests from MyRunner: " + testClass);
+ try {
+ Object testObject = testClass.newInstance();
+ for (Method method : testClass.getMethods()) {
+ if (method.isAnnotationPresent(Test.class)) {
+ notifier.fireTestStarted(Description
+ .createTestDescription(testClass, method.getName()));
+ method.invoke(testObject);
+ notifier.fireTestFinished(Description
+ .createTestDescription(testClass, method.getName()));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/testing-modules/mocks/README.md b/testing-modules/mocks/README.md
index 3cb20dcf92..3baefe072b 100644
--- a/testing-modules/mocks/README.md
+++ b/testing-modules/mocks/README.md
@@ -2,3 +2,10 @@
- [EasyMock Argument Matchers](http://www.baeldung.com/easymock-argument-matchers)
- [Mock Static Method using JMockit](https://www.baeldung.com/jmockit-static-method)
+- [Mockito vs EasyMock vs JMockit](http://www.baeldung.com/mockito-vs-easymock-vs-jmockit)
+- [Introduction to EasyMock](http://www.baeldung.com/easymock)
+- [JMockit 101](http://www.baeldung.com/jmockit-101)
+- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations)
+- [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage)
+- [Introduction to Jukito](http://www.baeldung.com/jukito)
+- [A Guide to JavaFaker](https://www.baeldung.com/java-faker)
diff --git a/testing-modules/mocks/javafaker/pom.xml b/testing-modules/mocks/javafaker/pom.xml
deleted file mode 100644
index 8c1f8c080e..0000000000
--- a/testing-modules/mocks/javafaker/pom.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
- 4.0.0
- javafaker
- javafaker
-
-
- com.baeldung
- mocks
- 1.0.0-SNAPSHOT
- ../
-
-
-
-
- com.github.javafaker
- javafaker
- ${javafaker.version}
-
-
-
-
- 0.15
-
-
-
diff --git a/testing-modules/mocks/jmockit/README.md b/testing-modules/mocks/jmockit/README.md
deleted file mode 100644
index 0e44b93d6e..0000000000
--- a/testing-modules/mocks/jmockit/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-=========
-
-## JMockit related tutorials
-
-
-### Relevant Articles:
-- [JMockit 101](http://www.baeldung.com/jmockit-101)
-- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations)
-- [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage)
diff --git a/testing-modules/mocks/jmockit/pom.xml b/testing-modules/mocks/jmockit/pom.xml
deleted file mode 100644
index 12bbe6b60d..0000000000
--- a/testing-modules/mocks/jmockit/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
- 4.0.0
- jmockit
- jmockit
-
-
- com.baeldung
- mocks
- 1.0.0-SNAPSHOT
- ../
-
-
-
-
- org.jmockit
- jmockit
- ${jmockit.version}
- test
-
-
-
-
- jmockit
-
-
- src/main/resources
- true
-
-
-
-
-
- 1.24
-
-
-
\ No newline at end of file
diff --git a/testing-modules/mocks/jukito/pom.xml b/testing-modules/mocks/jukito/pom.xml
deleted file mode 100644
index 752f097482..0000000000
--- a/testing-modules/mocks/jukito/pom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
- 4.0.0
- jukito
- jukito
-
-
- com.baeldung
- mocks
- 1.0.0-SNAPSHOT
- ../
-
-
-
-
- org.jukito
- jukito
- ${jukito.version}
- test
-
-
-
-
- 1.5
-
-
-
diff --git a/testing-modules/mocks/mock-comparisons/README.md b/testing-modules/mocks/mock-comparisons/README.md
deleted file mode 100644
index 20c13ecd72..0000000000
--- a/testing-modules/mocks/mock-comparisons/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-=========
-
-## Mock comparison realated tutorials
-
-
-### Relevant Articles:
-- [Mockito vs EasyMock vs JMockit](http://www.baeldung.com/mockito-vs-easymock-vs-jmockit)
-- [Introduction to EasyMock](http://www.baeldung.com/easymock)
diff --git a/testing-modules/mocks/mock-comparisons/pom.xml b/testing-modules/mocks/mock-comparisons/pom.xml
deleted file mode 100644
index e454f124ce..0000000000
--- a/testing-modules/mocks/mock-comparisons/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
- 4.0.0
- mock-comparisons
- mock-comparisons
-
-
- com.baeldung
- mocks
- 1.0.0-SNAPSHOT
- ../
-
-
-
-
- org.mockito
- mockito-core
- ${mockito.version}
- test
-
-
-
- org.easymock
- easymock
- ${easymock.version}
- test
-
-
-
- org.jmockit
- jmockit
- ${jmockit.version}
- test
-
-
-
-
-
- mock-comparisons
-
-
- src/main/resources
- true
-
-
-
-
-
- 2.21.0
- 3.5.1
- 1.41
-
-
-
diff --git a/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml b/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml
index ecc8b61a6d..342191c206 100644
--- a/testing-modules/mocks/pom.xml
+++ b/testing-modules/mocks/pom.xml
@@ -12,9 +12,45 @@
../../
-
- mock-comparisons
- jmockit
-
+
+
+ com.github.javafaker
+ javafaker
+ ${javafaker.version}
+
+
+ org.jmockit
+ jmockit
+ ${jmockit.version}
+ test
+
+
+ org.jukito
+ jukito
+ ${jukito.version}
+ test
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+ org.easymock
+ easymock
+ ${easymock.version}
+ test
+
+
+
+
+ 0.15
+ 1.5
+2.21.0
+ 3.5.1
+ 1.41
+
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/ArticleReader.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/ArticleReader.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/ArticleReader.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/ArticleReader.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/BaeldungArticle.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/BaeldungArticle.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/BaeldungArticle.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/BaeldungArticle.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/BaeldungReader.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/BaeldungReader.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/BaeldungReader.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/BaeldungReader.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/IArticleWriter.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/IArticleWriter.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/IArticleWriter.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/IArticleWriter.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/IUserService.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/IUserService.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/IUserService.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/IUserService.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/User.java b/testing-modules/mocks/src/main/java/com/baeldung/easymock/User.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/com/baeldung/easymock/User.java
rename to testing-modules/mocks/src/main/java/com/baeldung/easymock/User.java
diff --git a/testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/Calculator.java b/testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/Calculator.java
similarity index 100%
rename from testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/Calculator.java
rename to testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/Calculator.java
diff --git a/testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java b/testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java
similarity index 100%
rename from testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java
rename to testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java
diff --git a/testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java b/testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java
similarity index 100%
rename from testing-modules/mocks/jukito/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java
rename to testing-modules/mocks/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/com/baeldung/mocks/jmockit/AppManager.java b/testing-modules/mocks/src/main/java/com/baeldung/mocks/jmockit/AppManager.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/com/baeldung/mocks/jmockit/AppManager.java
rename to testing-modules/mocks/src/main/java/com/baeldung/mocks/jmockit/AppManager.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Model.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Model.java
diff --git a/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Performer.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/jmockit/Performer.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginController.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginController.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginDao.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginDao.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginService.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/LoginService.java
diff --git a/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java b/testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/UserForm.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java
rename to testing-modules/mocks/src/main/java/org/baeldung/mocks/testCase/UserForm.java
diff --git a/testing-modules/mocks/jmockit/src/main/resources/logback.xml b/testing-modules/mocks/src/main/resources/logback.xml
similarity index 100%
rename from testing-modules/mocks/jmockit/src/main/resources/logback.xml
rename to testing-modules/mocks/src/main/resources/logback.xml
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/ArgumentMatchersUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/ArgumentMatchersUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/ArgumentMatchersUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/ArgumentMatchersUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedWithRuleUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedWithRuleUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedWithRuleUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderAnnotatedWithRuleUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderMockDelegationUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderMockDelegationUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderMockDelegationUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderMockDelegationUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderMockSupportUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderMockSupportUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderMockSupportUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderMockSupportUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderUnitTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/com/baeldung/easymock/BaeldungReaderUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/easymock/BaeldungReaderUnitTest.java
diff --git a/testing-modules/mocks/jukito/src/test/java/com/baeldung/introductionjukito/CalculatorUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/introductionjukito/CalculatorUnitTest.java
similarity index 100%
rename from testing-modules/mocks/jukito/src/test/java/com/baeldung/introductionjukito/CalculatorUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/introductionjukito/CalculatorUnitTest.java
diff --git a/testing-modules/mocks/javafaker/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java
similarity index 100%
rename from testing-modules/mocks/javafaker/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java
diff --git a/testing-modules/mocks/jmockit/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java b/testing-modules/mocks/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java
rename to testing-modules/mocks/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java
diff --git a/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java
diff --git a/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java
diff --git a/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java
diff --git a/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java
diff --git a/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java b/testing-modules/mocks/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java
similarity index 100%
rename from testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java
rename to testing-modules/mocks/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java
diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml
index 5102e09349..c0eb59f15e 100644
--- a/testing-modules/pom.xml
+++ b/testing-modules/pom.xml
@@ -2,8 +2,8 @@
4.0.0
- testing-libraries
- testing-libraries
+ testing-modules
+ testing-modules
pom
@@ -14,6 +14,7 @@
+ assertion-libraries
easy-random
gatling
groovy-spock
@@ -37,5 +38,6 @@
junit-5-advanced
xmlunit-2
junit-4
+ testing-libraries
diff --git a/testing-modules/testing-libraries/README.md b/testing-modules/testing-libraries/README.md
new file mode 100644
index 0000000000..0cd9ca7f2e
--- /dev/null
+++ b/testing-modules/testing-libraries/README.md
@@ -0,0 +1,10 @@
+
+## Relevant Articles
+
+- [Mutation Testing with PITest](http://www.baeldung.com/java-mutation-testing-with-pitest)
+- [Intro to JaCoCo](http://www.baeldung.com/jacoco)
+- [Cucumber and Scenario Outline](http://www.baeldung.com/cucumber-scenario-outline)
+- [Cucumber Java 8 Support](http://www.baeldung.com/cucumber-java-8-support)
+- [Introduction to Lambda Behave](http://www.baeldung.com/lambda-behave)
+- [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java)
+
diff --git a/testing-modules-2/pom.xml b/testing-modules/testing-libraries/pom.xml
similarity index 95%
rename from testing-modules-2/pom.xml
rename to testing-modules/testing-libraries/pom.xml
index c919dbe90a..ab028cee24 100644
--- a/testing-modules-2/pom.xml
+++ b/testing-modules/testing-libraries/pom.xml
@@ -2,8 +2,8 @@
4.0.0
- testing-modules-2
- testing-modules-2
+ testing-libraries
+ testing-libraries
pom
diff --git a/testing-modules-2/src/main/java/com/baeldung/cucumber/Calculator.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/Calculator.java
similarity index 100%
rename from testing-modules-2/src/main/java/com/baeldung/cucumber/Calculator.java
rename to testing-modules/testing-libraries/src/main/java/com/baeldung/cucumber/Calculator.java
diff --git a/testing-modules-2/src/main/java/com/baeldung/lambdabehave/Calculator.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/lambdabehave/Calculator.java
similarity index 100%
rename from testing-modules-2/src/main/java/com/baeldung/lambdabehave/Calculator.java
rename to testing-modules/testing-libraries/src/main/java/com/baeldung/lambdabehave/Calculator.java
diff --git a/testing-modules-2/src/main/java/com/baeldung/mutation/Palindrome.java b/testing-modules/testing-libraries/src/main/java/com/baeldung/mutation/Palindrome.java
similarity index 100%
rename from testing-modules-2/src/main/java/com/baeldung/mutation/Palindrome.java
rename to testing-modules/testing-libraries/src/main/java/com/baeldung/mutation/Palindrome.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/calculator/CalculatorIntegrationTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/calculator/CalculatorIntegrationTest.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/calculator/CalculatorIntegrationTest.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/calculator/CalculatorIntegrationTest.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/calculator/CalculatorRunSteps.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/calculator/CalculatorRunSteps.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/calculator/CalculatorRunSteps.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/calculator/CalculatorRunSteps.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/lambdabehave/CalculatorUnitTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/lambdabehave/CalculatorUnitTest.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/lambdabehave/CalculatorUnitTest.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/lambdabehave/CalculatorUnitTest.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/mutation/PalindromeUnitTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/mutation/PalindromeUnitTest.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/mutation/PalindromeUnitTest.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/mutation/PalindromeUnitTest.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/shopping/ShoppingIntegrationTest.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/shopping/ShoppingIntegrationTest.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/shopping/ShoppingIntegrationTest.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/shopping/ShoppingIntegrationTest.java
diff --git a/testing-modules-2/src/test/java/com/baeldung/shopping/ShoppingStepsDef.java b/testing-modules/testing-libraries/src/test/java/com/baeldung/shopping/ShoppingStepsDef.java
similarity index 100%
rename from testing-modules-2/src/test/java/com/baeldung/shopping/ShoppingStepsDef.java
rename to testing-modules/testing-libraries/src/test/java/com/baeldung/shopping/ShoppingStepsDef.java
diff --git a/testing-modules-2/src/test/resources/features/calculator-scenario-outline.feature b/testing-modules/testing-libraries/src/test/resources/features/calculator-scenario-outline.feature
similarity index 100%
rename from testing-modules-2/src/test/resources/features/calculator-scenario-outline.feature
rename to testing-modules/testing-libraries/src/test/resources/features/calculator-scenario-outline.feature
diff --git a/testing-modules-2/src/test/resources/features/calculator.feature b/testing-modules/testing-libraries/src/test/resources/features/calculator.feature
similarity index 100%
rename from testing-modules-2/src/test/resources/features/calculator.feature
rename to testing-modules/testing-libraries/src/test/resources/features/calculator.feature
diff --git a/testing-modules-2/src/test/resources/features/shopping.feature b/testing-modules/testing-libraries/src/test/resources/features/shopping.feature
similarity index 100%
rename from testing-modules-2/src/test/resources/features/shopping.feature
rename to testing-modules/testing-libraries/src/test/resources/features/shopping.feature