Ruby Testing Micro-Course, Lesson 3

by Jason Swett,

Lesson 1 / Lesson 2 / Lesson 3 / Lesson 4

Review of Lesson 2

In Lesson 2 I gave you a chance to compare the test you wrote in Lesson 1 to my version of the same test, and I showed you exactly how I came up with that test. Then we began planning features for checking guests into specific rooms.

Also in Lesson 2, we established that the following things should be true for room functionality:

  1. Add the guest to the hotel’s guest list (we’re already testing for this)
  2. Disallow another guest from checking into that same room
  3. Decrease the total number of available rooms

What We’ll Do In Lesson 3

In Lesson 3 we’re going to write a test that ensures we don’t allow a guest to check into a room that’s already checked out by another guest.

Then I’ll give you a chance to write your own test that says, “When we check a guest out of a room, that room should get freed up.”

Test for Room Availability

Right now our check_in_guest method takes whatever guest_name we give it and happily adds that guest_name onto the @guests array. There’s no concept of success or failure. The check_in_guest method just always works, regardless of whether it really should work or not.

Let’s change this. Let’s make it so if we try to check a new guest into a room that’s already checked out by another guest, check_in_guest will return false.

And of course, check_in_guest should return true if the room is free and the new guest was successfully checked in.

We’ll begin by adding two test cases: one for the “room is available” case and one for the “room is not available” case.

When we run our test suite, both of our new tests will fail. We’re expecting true and false but check_in_guest doesn’t return true or false. It returns the value of @guests.

Let’s make check_in_guest return something closer to what our tests our expecting.

This might seem like a silly move but we can make one of the two tests pass by simply hard-coding a return value of true for check_in_guest.

Now we only have one test failure instead of two.

Again, this might seem like a silly thing to have done but I like to do stuff like this when I’m developing tests. It gives me one less thing to think about when I’m working on the next step. There’s also just something nice and neat about “expected false and got true” versus “expected false and got some crazy unexpected value”.

Returning False If Room Is Occupied

Now we have to do the “harder” work of making check_in_guest actually return false if the room is occupied.

Right now a Hotel instance doesn’t have a concept of occupied rooms at all. All it knows is which guests are checked into the hotel.

Let’s add a list of occupied rooms to our class. When we check in a guest, check_in_guest will now not only add guest_name to our list of guests but it will add room_number to a list of occupied rooms.

Now all our tests will pass.

Here’s the full hotelier_spec.rb file in case you got lost in the course of following the above steps.

Bug: Guest Will Get Added Even If Room Is Occupied

You might have noticed an issue with our latest version of check_in_guest.

Notice how it adds guest_name to @guests before it checks to see whether the room is actually available or not.

I added this mistake intentionally to show that our current test suite is not as complete as it needs to be.

Let’s fix this bug, but first let’s add a test that ensures that attempting to check in a guest to an unavailable room does not add that guest to the hotel’s guest list.

Our test will of course fail because we haven’t fixed check_in_guest yet.

Now let’s fix check_in_guest by moving the “is this room occupied?” check to be on the first line.

Now all five of our tests pass.

Here’s the full hotelier_spec.rb file for reference.

Refactoring

Our test suite is a little repetitive. We have hotel = Hotel.new all over the place. Let’s make our tests a little more DRY.

Exercise: Freeing Up a Room

If checking a guest into a room makes that room unavailable, checking a guest out of a room should make that room available again. Right now our code doesn’t do that.

See if you can write a test that ensures that checking out a guest frees up that room. Feel free to also write the code that makes that test pass, but not before you write the test.

I’ll see you in the final lesson, Lesson 4, where you can see how I wrote my test for freeing up a room.

Continue to Lesson 4 >>>

  •  
  •  
  •  
  •  

Leave a Reply

Your email address will not be published. Required fields are marked *