Do you remember when a couple of scenarios were missing and we discovered them through production code?
Completeness checks?
The missing scenarios we need to take care about are overbooking flights and remembering the actual
bookings.
We implemented the avoiding bookings scenario already.
But if we take a look at the production code, we find out that we don't track the booking record anywhere.
We need to know who has booked which flight for how many passengers later.
In another word, we simply need to remember all the bookings.
We should first consider the steps of this scenario.
Let's start from the when step.
When I book a flight, then the booking list of the flight should include my booking.
And of course, a flight should initially exist to be able to book it.
Now let's translate it to code.
The test method name can be remember booking since it's inside the flight specification class.
I can read it like flight.
Remember booking right at the given step.
The flight's capacity doesn't matter in this test.
It's a dummy variable.
It should have enough capacity to accommodate the number of seats we are going to book.
So I'll set it to a relatively big number when a passenger with the email a@b.com books four seats off
the flight, then the flight's booking list should contain a booking made by A and b.com for four seats.
The test code is clear and understandable by any developer or even someone who is familiar with programming.
Now let's discover a new scenario which we will have talked about in the previous video, which is actually
saving the bookings.
So what we do now is we again implement a new test for that.
So as always, because this is a test driven approach, right?
We create our test here.
First fact, public void, let's call it remembers bookings.
There we go.
Remember, it's bookings.
And again, we have a flight.
Var flight equals to new flight.
Let's create one with a realistic number of seat capacity, which potentially could be something like
maybe 150 or something like that.
All right, so let's flight dot book, let's book something, for example, passenger email.
Let's do exactly what we have done in the presentation.
so@b.com and let's book number of seats four So for sure, you don't really have to write down the parameter
names, but that's easier to read and therefore easier to maintain from a test side of view, right?
So because you can directly see, okay, four is like number of seats.
So here we have a good practice to write down the actual parameter name too.
And for that we really have all the information that we need.
We have a flight class, we have a booking method or a book method, and now it's time to write down
a new logic which we need to implement then by following along the arrows.
So I want that the flight itself should have a booking list so that one should contain all the email
addresses and the amount of booked seats.
So the number of seats that the person has booked for the flight.
So booking list we need to create that dot should dot and now pay attention.
We have a new method here.
Should contain a new booking of well, A at B dot com.
So the email address, we could parameterize that for sure.
And the exactly same amount of the number of seats right here.
So this is what we have to implement now.
But for sure in TDD we first of all write the test and now only write the production code to make the
test pass.
Great.
So let's save it.
Open up the error list.
I got that here.
And the first error that I can see is flight does not contain a definition for booking list.
So let's add a booking list to the flight instead of the flight here, let me just go to the class that
we have here.
We for sure want to extend it by a list of type booking.
So we need to create a booking class, right?
So inside of our domain, we got that domain project right here, right click on it and create a new
C sharp class.
And we call that class simply booking.
Just give it a second to load here.
So booking and we can leave it as a class so we can make it a class, switch it over to be public,
not internal, or we can make it a record.
And the main difference between the class and the record is that a record cannot get changed in easy
terms.
So it's immutable, It cannot get changed once it got created, basically.
Right.
But let's assume you are able to change your booking after creating for your business logic.
However, then we stick with the class here.
If you don't want to change it later on, you could potentially use a new sort of C sharp record here.
Great.
So that booking simply contains, well, two properties, right?
So the first one that we have is the passenger email and the number of seats.
So let's write down prop, let's give it a string and let's call it email.
So who has booked that booking or who is like the owner of that booking?
And we have another property of type INT, which is the number of seats that the person has booked.
Number of seats.
Awesome.
This is all we have to do.
Let's switch over to our flight again and.
This time.
We take a look here at the flight class and we add another property, which is prop and we add a list
here.
So prop list of type booking, you can see that and we call that booking list.
So this specific flight going from Germany to Dubai, for example, has a booking list with all the
passengers like Yannick or a ABC.com has booked four seats.
Right.
Something like that.
Okay.
As I said, we are not really caring too much about the actual logical code because we are really covering
the TDD approach.
But for sure we want to make this as complete as possible.
Great.
Now let's switch over to our flight specifications again and you can see that we have flight booking
list here, which is already fine, but we cannot create a new booking.
And this is because he said that we don't have a constructor.
That takes two arguments.
So let's again switch over to the booking and let's create a constructor.
So what we do is we simply go ahead and write down C tour, which is the shortcut for constructor.
Top top.
There we go.
We have our constructor defined.
Let's go string, email and string sorry, int number of seats.
And then next up we assign it.
So this dot email equals to email from the parameter.
And this dot number of seats equals to number of seats.
Nice.
So this is all we have to do.
Let's switch over to the flight specifications again.
You can see now we have a constructor, we can submit a ABC.com and for sure the number of seats we
want to book.
So we have no compilation error here anymore, so that should work out fine now.
So let's see what our test results are saying right click on that and run tests.
So let's see what happens when the tests are loaded.
Awesome.
For sure the test is failing because, well, the statement in line 51 for me flight booking lists should
contain a new booking is never going to be true because we never add a booking to that booking list.
Right?
So here you can see expected flight booking list to contain a booking with email, a, B and number
of seats four.
So in order to write the production code, now we switch to the flight class and where we book a flight
which is here inside of the book method, we will now for sure add a booking and we do that after checking
for overbook, right?
So let's do that.
We simply say, or we can also do that even after subtracting.
The number of seats.
So let's go ahead.
Booking list, dot Add and we add a new booking.
And here we create for sure the constructor passenger email and number of seats.
So we create an instance of that booking class using the passenger email, a number of seat from the
parameter.
Great.
So if we save it now, switch back to the flight specification, right click on it and run the test
again.
We should see that test being successful.
Oh yeah.
And now we got an error which is like object reference not set to an instance of an object, which actually
means that the booking list here is null.
So in order to fix that, I mean, that's the great part about it, right?
This is exactly why you have TDD.
So I will not cut it out if there happens a mistake during recording right now because it's an actual
well failure of mine and I can use TDD to fix the issue.
So the problem is that booking list is null.
So what we do here to fix that is to well create a new list of type booking so that we have an instance
of well a list of type booking, right?
So this is no longer null when we try to access it here.
Awesome.
Let's save it and go to flight specification again.
Right click on it and again run test.
So this is like a perfect example of why you should use TDD.
Because if I wouldn't have tested it right now, it would be simple like exception and null reference
exception in runtime and you don't want to have that right.
So let's see it expected the flight booking list with A and B to contain A booking A and b.com number
of seats four.
You can see that it's still not working.
Right?
So the test is failing and that's because of the contain here.
And I want to make sure that I explain it because it just happened to me right now.
And as I said, I won't remove it.
I want to explain it instead.
So the contain checks for the reference type.
So if we create an object here, which we are doing right, so we are creating a booking entry or a
booking instantiation and that should be then inside of the booking list and should contain, well,
not a new booking.
So here we create an object and here we also create an object.
And those two objects could never be the same.
And this is why contain will never be true and this is why we not use contain here.
However, we could use contain if we change the structure of the code by, for example, returning from
the book and actual booking and then using that booking inside that call.
Then we could use contain because the reference is matching to one object.
Then, however, if we want to use it like this, we use another method which is equivalent here contain
equivalent of.
So this is really checking for like the structure and not for the actual real object reference.
So contain equivalent of and this now checks if we have like a booking with exactly this values inside
of the booking list.
So those values here and here and this will now work once we run the tests again, you can see that
the test passes well.
And so, yeah, this is some expert knowledge, right?
So you really want to pay attention on that.
So if you write tests and you really want to check, for instance, for a very specific instance, so
that one single object and no, not another object, not a new one, exactly that one you can use contain.
But if you just check for structure and values of properties, for example, you have to use contain
equivalent of because we are creating a new object here, a new booking, and that could never be the
one which gets created here in the book call to because you can see that we create also a new one here.
So we are creating two and they can never be exactly the same one for sure.
Okay.
And now you can see that our tests are working again.