We first thought about the test scenario and visualized it using those sticky notes right here.
Then we translated the sticky notes to the test.
There is a general pattern for dividing steps of a test scenario.
Some test scenarios have preconditions as we talked about it already.
Right.
Preparing the preconditions is the very first step.
We call this step the given step.
The given step is the test scenario.
The given step in a test scenario was creating a new flight with a seat capacity of three.
Then there is the when step of what triggers the action.
The when step in.
Our scenario was to book a flight with the number of seats of one.
And the final step is the then step.
The then step describes the expected outcome of the scenario in our test scenario.
The then step was that the number of remaining seats was expected to be two.
The flight class was our system under test the subject which we were testing its behavior.
Our test had three steps.
We can read it like this.
Given a new flight with a seat capacity of three, when I book the flight of a seat, then the flight's
number of remaining seats should be to the given when then format is just a pattern that makes it easy
to communicate with business people and developers.
Right?
When developers look at your code, they expect the code of given when and then steps to be explicitly
separated from each other.
As you can see it right here, the code was separated, given when and then steps is easier to understand.
We wrote each step in a separate line.
The book method now looks like this.
It's reducing the number of seats of the book method should really do well.
Obviously not.
The book method should also prevent the passengers from overbooking the flight.
And it should also remember all of the bookings that passengers make.
What we implement in entities should happen in the business domain, even if there is no software in
between the routes that business stakeholders expect from the operations in the business domain.
In our flight booking example here, even if the stakeholders use pen and paper to book flights, they
should avoid overbooking.
Right?
Remember the booking and the reduced number of seats by each booking.
So they finally store that piece of paper somewhere to keep track of everything.
We store the entity, for example, in a database, but that doesn't mean we should copy the process
from the existing manual system.
So we should first analyze design and finally implement the software.
Since covering analysis and design is outside this course scope for sure, let's implement the new scenarios,
avoid overbooking flights and remembering the bookings.
Let's start with the avoiding overbooking scenario.
As always, we don't want to jump into code.
We want to think about the scenario without letting the compiler get in our way.
So let's see what avoiding overbooking the flight means.
It means that if the number of remaining seats is bigger than the number of passengers that the passenger
wants to book, the flight entity should return an error instead of booking the flight.
But how do we test this scenario?
Should you should find a way to test this scenario.
You should consider what parameters you need to pass the test flight entity and how to measure the outcome.
We don't want to think about how to implement it yet.
We want to think about how to test if the flight entity avoids overbooking.
At this point, imagine that you want to see if your teammate has implemented the overbooking behavior
without looking at the code base.
So you run the application, pass some inputs and check the output to check if the flight entity avoids
overbooking, you run the application and booking and book four seats on the flight that only has three
seats remaining and see if the application shows an overbooking error.
So even if someone else implements the logic for it, you can write a simple test and check if the implementation
of the code is actually working.
And whenever you don't know how to test the required behavior, consider how you would check if an existing
application already has this behavior.
So you can use sticky notes, for example, like we did right here to visualize the steps.
Once you discover the steps, we translate them to test code.
So let's translate the avoiding overbook scenario together.
And let's start with the test methods.
Name Test Method Name should describe a flight's behavior.
We can name this method.
For example, Flight avoids overbooking, and since the method is going to be in the flight specifications
class, we can omit the flight from the test methods name so the test methods name ends up avoid overbooking.
It's time to translate the steps.
Given a new flight with three seats capacity.
When I booked for four seats, then an error of type overbooking error should be returned.
The email address does nothing in this scenario, but since we have to call the book method, we have
to fill the parameter with something valid.
Write.
Such parameters are called dummies.
You might wonder why you should pass that parameter.
The decision is made by the designer of the entity when he was designing the domain model.
Domain modeling is outside of this scope of this course because we are just talking about TDD, not
software designing in general.
So now let's again get our hands dirty and implement the avoid overbooking scenario in a TDD approach.