Test Driven Development with JUnit 5. Part 3
3. Preparing the flight-management application for TDD
To move the flight-management application to TDD, we first need to cover the existing business logic with JUnit 5 tests. We add the JUnit 5 dependencies (junit-jupiter-api and junit-jupiter-engine) to the Maven pom.xml file.
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Inspecting the business logic, we understand that we have to check the add/remove passenger scenarios by providing tests for two flight types and two passenger types. So, multiplying two flight types by two passenger types, this means four tests in total. For each of the tests, we have to verify the possible add and remove operations.
We follow the business logic for an economy flight and use the JUnit 5 nested test capability, as the tests share similarities between them and can be grouped: tests for economy flights and tests for business flights.
public class AirportTest {
@DisplayName("Given there is an economy flight") #1
@Nested #1
class EconomyFlightTest { #1
private Flight economyFlight; #2
@BeforeEach #2
void setUp() { #2
economyFlight = new Flight("1", "Economy"); #2
} #2
@Test
public void testEconomyFlightRegularPassenger() {
Passenger mike = new Passenger("Mike", false); #3
assertEquals("1", economyFlight.getId()); #4
assertEquals(true, economyFlight.addPassenger(mike)); #5
assertEquals(1, economyFlight.getPassengersList().size()); #5
assertEquals("Mike", #5
economyFlight.getPassengersList().get(0).getName()); #5
assertEquals(true, economyFlight.removePassenger(mike)); #6
assertEquals(0, economyFlight.getPassengersList().size()); #6
}
@Test
public void testEconomyFlightVipPassenger() {
Passenger james = new Passenger("James", true); #7
assertEquals("1", economyFlight.getId()); #8
assertEquals(true, economyFlight.addPassenger(james)); #9
assertEquals(1, economyFlight.getPassengersList().size()); #9
assertEquals("James", #9
economyFlight.getPassengersList().get(0).getName()); #9
assertEquals(false, economyFlight.removePassenger(james)); #10
assertEquals(1, economyFlight.getPassengersList().size()); #10
}
}
}
In this listing:
- We declare a nested test class EconomyFlightTest and labels it "Given there is an economy flight" with the help of the @DisplayName annotation #1.
- We declare an economy flight and initializes it before the execution of each test #2.
- When testing how the economy flight works with a regular passenger, we create Mike as a regular passenger #3. Then, we check the ID of the flight #4, whether we can add Mike on the economy flight and that we can find Mike there #5, and whether we can remove Mike from the economy flight and that Mike is no longer there #6.
- When testing how the economy flight works with a VIP passenger, we create James as a VIP passenger #7. Then, we check the ID of the flight #8, whether we can add James on the economy flight and that we can find James there #9, and whether we cannot remove James from the economy flight and that James is still there #10.
- We follow the business logic for a business flight and translate it into the following tests.
public class AirportTest {
[...]
@DisplayName("Given there is a business flight") #1
@Nested #1
class BusinessFlightTest { #1
private Flight businessFlight; #2
@BeforeEach #2
void setUp() { #2
businessFlight = new Flight("2", "Business"); #2
} #2
@Test
public void testBusinessFlightRegularPassenger() {
Passenger mike = new Passenger("Mike", false); #3
assertEquals(false, businessFlight.addPassenger(mike)); #4
assertEquals(0, businessFlight.getPassengersList().size()); #4
assertEquals(false, businessFlight.removePassenger(mike)); #5
assertEquals(0, businessFlight.getPassengersList().size()); #5
}
@Test
public void testBusinessFlightVipPassenger() {
Passenger james = new Passenger("James", true); #6
assertEquals(true, businessFlight.addPassenger(james)); #7
assertEquals(1, businessFlight.getPassengersList().size()); #7
assertEquals(false, businessFlight.removePassenger(james)); #8
assertEquals(1, businessFlight.getPassengersList().size()); #8
}
}
}
In this listing:
- We declare a nested test class BusinessFlightTest and labels it "Given there is a business flight" with the help of the @DisplayName annotation #1.
- We declare a business flight and initializes it before the execution of each test #2.
- When testing how the business flight works with a regular passenger, we create Mike as a regular passenger #3. Then, we check that we cannot add Mike to the business flight #4 and that trying to remove Mike from the business flight also has no effect #5.
- When testing how the business flight works with a VIP passenger, we create James as a VIP passenger #6. Then, we check that we can add James to the business flight and that we can find James there #7 and that we cannot remove James from the business flight and that James still there #8.
The tests run successfully.
We have successfully verified the functionality of the application by writing tests for all the scenarios that result from the business logic. It is possible that in real life you may begin working with an application that has no tests and want to move to TDD. Before you do, you will have to test the application as it is.