AssertJ
Extension of Junit testing library that provides assertion methods. In a fluent way you can assert:
Common types: Optional, Predicates, Streams, Itreable
Primitive types
Java 8 Temporal Types
Atomic Types
It adds to the redability of the tests.
Some of the features
- Recursive comparision by field. Compares two objects from different classes. Like entity and dto objects. AssertJ goes filed by filed on objects and compare values of the fileds.
@Test
public void testPerson() {
var p1 = new Person("John", 20);
var p2 = new PersonDto("John", 20);
assertThat(p1).usingRecursiveComparison().isEqualTo(p2);
// assertThat(p1).isEqualTo(p2);
}
- Soft assertions. Collects all assertion errors instead of stopping at the first one.
@Test
public void softAssertionTest() {
var p1 = new Person("John 2", 20);
SoftAssertions.assertSoftly(soft -> {
soft.assertThat(p1.getName()).isEqualTo("Not John");
soft.assertThat(p1.getAge()).isEqualTo(22);
});
}
Multiple Failures (2 failures)
-- failure 1 --
expected: "Not John"
but was: "John 2"
at PersonTest.lambda$softAssertionTest$0(PersonTest.java:28)
-- failure 2 --
expected: 22
but was: 20
at PersonTest.lambda$softAssertionTest$0(PersonTest.java:29)
- Custom assertions. Create your own validation.
class PersonAssertion extends AbstractAssert<PersonAssertion, Person> {
protected PersonAssertion(Person actual) {
super(actual, PersonAssertion.class);
}
public static PersonAssertion assertThat(Person person) {
return new PersonAssertion(person);
}
public PersonAssertion isAdult() {
if (actual.getAge() < 18) {
failWithMessage("Not adult");
}
return this;
}
}
// ...
// in the test class
@Test
public void customAssertionTest() {
var p1 = new Person("John 2", 20);
PersonAssertion.assertThat(p1).isAdult();
}
Rest-Assured
Java API testing library for REST based services based on the given-when-then keywords (not BDD) - DSL for API testing.
@Test
public void testGet() {
Person personResponse =
when().
get("/person/1").
then().
statusCode(200).
extract().as(Person.class);
assertThat(personResponse.getName()).isEqualTo("John");
}
We can fast create the test architecture and decrease the test maintenance by:
Using the openapi-generator to create the client based on REST Assured
Create a service layer in the test project
Awaitility
During the test to wait for an asynchronous system (RabbitMQ, Apache Kafka, Redis...) to complete the request. You can:
- Create conditions to wait
- Check fields
- Support for Atomic
- Ignoring and checking exceptions
- Integrate with AssertJ
@Test
public void updatesCustomerStatus() {
// Publish an asynchronous message to a broker (e.g. RabbitMQ):
messageBroker.publishMessage(updateCustomerStatusMessage);
// Awaitility lets you wait until the asynchronous operation completes:
await().atMost(5, SECONDS).until(customerStatusIsUpdated());
...
}
WireMock
Open source tool for API mock testing. It constructs an HTTP server that we can connect to as we would to an actual web service.
Instead of mocking something you need, that will be duplicated across the teams you can implement a Service Virtualization approach using WireMock to share the same mock across multiple teams.
PiTest (PIT)
Mutation testing library. It tryes detect faults in the code base on a series code chaged. Showing you if your code base had lived of killed mutations:
Lived mutations: indicated you have something to work on
Killed mutatiuons: the change applied is covered
When the application code changes, it should produce different results and cause the unit tests to fail. If a unit test does not fail in this situation, it may indicate an issue with the test suite. PiTest changes the code (mutates the code):
- Conditional Boundary
- Increment
- Math
Top comments (2)
Don't forget testcontainers, IMHO this is a must
yes you are right :) I guess we need one more post