Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Browser testing is essential if you have a website or web applications that users interact with. Manual testing can be very helpful to an extent, but given the multiple browsers available, not to mention versions and operating system, testing everything manually becomes time-consuming and repetitive.

To help automate this process, Selenium is a popular choice for developers, as an open-source tool with a large and active community. What's more, we can further scale our automation testing by running on theLambdaTest cloud-based testing platform.

Read more through our step-by-step tutorial on how to set up Selenium tests with Java and run them on LambdaTest:

>> Automated Browser Testing With Selenium

Partner – Orkes – NPI EA (cat=Java)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI (cat= Testing)
announcement - icon

Browser testing is essential if you have a website or web applications that users interact with. Manual testing can be very helpful to an extent, but given the multiple browsers available, not to mention versions and operating system, testing everything manually becomes time-consuming and repetitive.

To help automate this process, Selenium is a popular choice for developers, as an open-source tool with a large and active community. What's more, we can further scale our automation testing by running on the LambdaTest cloud-based testing platform.

Read more through our step-by-step tutorial on how to set up Selenium tests with Java and run them on LambdaTest:

>> Automated Browser Testing With Selenium

1. Overview

Test runner frameworks like JUnit and TestNG provide some basic assertion methods (assertTrue, assertNotNull, etc.).

Then there are assertion frameworks like Hamcrest, AssertJ, and Truth, which provide fluent and rich assertion methods with names that usually begin with “assertThat”.

JSpec is another framework that allows us to write fluent assertions closer to the way we write specifications in our natural language, albeit in a slightly different manner from other frameworks.

In this article, we’ll learn how to use JSpec. We’ll demonstrate the methods required to write our specifications and the messages that will print in case of test failure.

2. Maven Dependencies

Let’s import the javalite-common dependency, which contains JSpec:

<dependency>
    <groupId>org.javalite</groupId>
    <artifactId>javalite-common</artifactId>
    <version>1.4.13</version>
</dependency>

For the latest version, please check the Maven Central repository.

3. Comparing Assertion Styles

Instead of the typical way of asserting based on rules, we just write the specification of behavior. Let’s look at a quick example for asserting equality in JUnit, AssertJ, and JSpec.

In JUnit, we’d write:

assertEquals(1 + 1, 2);

And in AssertJ, we’d write:

assertThat(1 + 1).isEqualTo(2);

Here’s how we’d write the same test in JSpec:

$(1 + 1).shouldEqual(2);

JSpec uses the same style as fluent assertion frameworks but omits the leading assert/assertThat keyword and uses should instead.

Writing assertions in this way makes it easier to represent the real specifications, promoting TDD and BDD concepts.

Look how this example is very close to our natural writing of specifications:

String message = "Welcome to JSpec demo";
the(message).shouldNotBe("empty");
the(message).shouldContain("JSpec");

4. Structure of Specifications

The specification statement consists of two parts: an expectation creator and an expectation method.

4.1. Expectation Creator

The expectation creator generates an Expectation object using one of these statically imported methods: a(), the(), it(), $():

$(1 + 2).shouldEqual(3);
a(1 + 2).shouldEqual(3);
the(1 + 2).shouldEqual(3);
it(1 + 2).shouldEqual(3);

All these methods are essentially the same — they all exist only for providing various ways to express our specification.

The only difference is that the it() method is type-safe, allowing comparison only of objects that are of the same type:

it(1 + 2).shouldEqual("3");

Comparing objects of different types using it() would result in a compilation error.

4.2. Expectation Method

The second part of the specification statement is the expectation method, which tells about the required specification like shouldEqual, shouldContain.

When the test fails, an exception of the type javalite.test.jspec.TestException displays an expressive message. We’ll see examples of these failure messages in the following sections.

5. Built-in Expectations

JSpec provides several kinds of expectation methods. Let’s take a look at those, including a scenario for each that shows the failure message that JSpec generates upon test failure.

5.1. Equality Expectation

shouldEqual(), shouldBeEqual(), shouldNotBeEqual()

These specify that two objects should/shouldn’t be equal, using the java.lang.Object.equals() method to check for equality:

$(1 + 2).shouldEqual(3);

Failure scenario:

$(1 + 2).shouldEqual(4);

would produce the following message:

Test object:java.lang.Integer == <3>
and expected java.lang.Integer == <4>
are not equal, but they should be.

5.2. Boolean Property Expectation

shouldHave(), shouldNotHave()

We use these methods to specify whether a named boolean property of the object should/shouldn’t return true:

Cage cage = new Cage();
cage.put(tomCat, boltDog);
the(cage).shouldHave("animals");

This requires the Cage class to contain a method with the signature:

boolean hasAnimals() {...}

Failure scenario:

the(cage).shouldNotHave("animals");

would produce the following message:

Method: hasAnimals should return false, but returned true

shouldBe(), shouldNotBe()

We use these to specify that the tested object should/shouldn’t be something:

the(cage).shouldNotBe("empty");

This requires the Cage class to contain a method with the signature “boolean isEmpty()”.

Failure scenario:

the(cage).shouldBe("empty");

would produce the following message:

Method: isEmpty should return true, but returned false

5.3. Type Expectation

shouldBeType(), shouldBeA()

We can use these methods to specify that an object should be of a specific type:

cage.put(boltDog);
Animal releasedAnimal = cage.release(boltDog);
the(releasedAnimal).shouldBeA(Dog.class);

Failure scenario:

the(releasedAnimal).shouldBeA(Cat.class);

would produce the following message:

class com.baeldung.jspec.Dog is not class com.baeldung.jspec.Cat

5.4. Nullability Expectation

shouldBeNull(), shouldNotBeNull()

We use these to specify that the tested object should/shouldn’t be null:

cage.put(boltDog);
Animal releasedAnimal = cage.release(dogY);
the(releasedAnimal).shouldBeNull();

Failure scenario:

the(releasedAnimal).shouldNotBeNull();

would produce the following message:

Object is null, while it is not expected

5.5. Reference Expectation

shouldBeTheSameAs(), shouldNotBeTheSameAs()

These methods are used to specify that an object’s reference should be the same as the expected one:

Dog firstDog = new Dog("Rex");
Dog secondDog = new Dog("Rex");
$(firstDog).shouldEqual(secondDog);
$(firstDog).shouldNotBeTheSameAs(secondDog);

Failure scenario:

$(firstDog).shouldBeTheSameAs(secondDog);

would produce the following message:

references are not the same, but they should be

5.6. Collection and String Contents Expectation

shouldContain(), shouldNotContain()
We use these to specify that the tested Collection or Map should/shouldn’t contain a given element:

cage.put(tomCat, felixCat);
the(cage.getAnimals()).shouldContain(tomCat);
the(cage.getAnimals()).shouldNotContain(boltDog);

Failure scenario:

the(animals).shouldContain(boltDog);

would produce the following message:

tested value does not contain expected value: Dog [name=Bolt]

We can also use these methods to specify that a String should/shouldn’t contain a given substring:

$("Welcome to JSpec demo").shouldContain("JSpec");

And although it may seem strange, we can extend this behavior to other object types, which are compared using their toString() methods:

cage.put(tomCat, felixCat);
the(cage).shouldContain(tomCat);
the(cage).shouldNotContain(boltDog);

To clarify, the toString() method of the Cat object tomCat would produce:

Cat [name=Tom]

which is a substring of the toString() output of the cage object:

Cage [animals=[Cat [name=Tom], Cat[name=Felix]]]

6. Custom Expectations

In addition to the built-in expectations, JSpec allows us to write custom expectations.

6.1. Difference Expectation

We can write a DifferenceExpectation to specify that the return value of executing some code should not be equal to a particular value.

In this simple example we’re making sure that the operation (2 + 3) will not give us the result (4):

expect(new DifferenceExpectation<Integer>(4) {
    @Override
    public Integer exec() {
        return 2 + 3;
    }
});

We can also use it to ensure that executing some code would change the state or value of some variable or method.

For example, when releasing an animal from a Cage that contains two animals, the size should be different:

cage.put(tomCat, boltDog);
expect(new DifferenceExpectation<Integer>(cage.size()) {
    @Override
    public Integer exec() {
        cage.release(tomCat);
        return cage.size();
    }
});

Failure scenario:

Here we’re trying to release an animal that doesn’t exist inside the Cage:

cage.release(felixCat);

The size won’t be changed, and we get the following message:

Objects: '2' and '2' are equal, but they should not be

6.2. Exception Expectation

We can write an ExceptionExpectation to specify that the tested code should throw an Exception.

We’ll just pass the expected exception type to the constructor and provide it as a generic type:

expect(new ExceptionExpectation<ArithmeticException>(ArithmeticException.class) {
    @Override
    public void exec() throws ArithmeticException {
        System.out.println(1 / 0);
    }
});

Failure scenario #1:

System.out.println(1 / 1);

As this line wouldn’t result in any exception, executing it would produce the following message:

Expected exception: class java.lang.ArithmeticException, but instead got nothing

Failure scenario #2:

Integer.parseInt("x");

This would result in an exception different from the expected exception:

class java.lang.ArithmeticException,
but instead got: java.lang.NumberFormatException: For input string: "x"

7. Conclusion

Other fluent assertion frameworks provide better methods for collections assertion, exception assertion, and Java 8 integration, but JSpec provides a unique way for writing assertions in the form of specifications.

It has a simple API that let us write our assertions like natural language, and it provides descriptive test failure messages.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)