Rspec TDD Kata: FizzBuzz
About this series
TDD(Test-Driven Development) is very effective for many type of projects. But I don’t understood it well. I’ll write a new series of TDD learning. So, let’s try it out!
I’m a Ruby on Rails developer. So I’ll use Rspec in Ruby on Rails to implement this series.
My Enviroment
Ruby 2.2.2Rails 5.1.6RSpec 3.7
The Training Kata is from: codingdojo
3 laws of TDD
Before start first training kata. Let’s review the laws of TDD again.
- Do not write any production code without a failing test first.
- Write only enough test code as is sufficient enough to fail.
- Only implement a minimal code that makes the failing test pass.
FizzBuzz
Problem Description
Imagine the scene. You are eleven years old, and in the five minutes before the end of the lesson, your Maths teacher decides he should make his class more “fun” by introducing a “game”. He explains that he is going to point at each pupil in turn and ask them to say the next number in sequence, starting from one. The “fun” part is that if the number is divisible by three, you instead say “Fizz” and if it is divisible by five you say “Buzz”. So now your maths teacher is pointing at all of your classmates in turn, and they happily shout “one!”, “two!”, “Fizz!”, “four!”, “Buzz!”… until he very deliberately points at you, fixing you with a steely gaze… time stands still, your mouth dries up, your palms become sweatier and sweatier until you finally manage to croak “Fizz!”. Doom is avoided, and the pointing finger moves on.
So of course in order to avoid embarassment infront of your whole class, you have to get the full list printed out so you know what to say. Your class has about 33 pupils and he might go round three times before the bell rings for breaktime. Next maths lesson is on Thursday. Get coding!
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz “.
Sample output:
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
... etc up to 100
Stage 2 — new requirements
* A number is fizz if it is divisible by 3 or if it has a 3 in it
* A number is buzz if it is divisible by 5 or if it has a 5 in it
Solution
How to build a rspec in rails project? read me
Target model: FizzBuzz
value: string. Store the real value of numbers
fizzbuzz: string. If multiples of 3, turn to "Fizz". If multiple of 5, turn to "Buzz". And multiples of 15 turn to "FizzBuzz".
Before start: How to name a Unit Test?
Why the name of this test is start from a dot? Because I want make a class method to satisfied this test case. In Ruby and many programing language, .
means a Class Method. And #
means a Instance Method.
And why don’t I write a sentence like Make sure it can count 1 to 100 ? This is another habit in writing spec. Better Spec suggest us:
Be clear about what method you are describing. For instance, use the Ruby documentation convention of
.
(or::
) when referring to a class method's name and#
when referring to an instance method's name.
1. Make up the test elements
I make a arrayFizzBuzz
by using let!
, push FizzBuzz
objects that have value 1 to 100 with before(:each)
.
2. The multiples of 3 should be “Fizz”
In fizz_buzz_spec.rb
we assume when fizzbuzz.value
multiples of 3 will return "Fizz"
. This is the test unit:
Then I run:
> rspec
It return failed. And error message are:
As we didn’t do anything. Rspec expected 3
would return Fizz
but it’s still 3
. So we need to write a method name .to_Fizz
in FizzBuzz
model.
Then we’ve got this error:
In this error, we can see the test case expected the object to be:
#<String:47302356286420>
But it return:
#<String:47302356286560>
They have same value but they are still different object. And the equal method can pass only if two same object, not only same value. Is like ==
vs ===
in Javascript and some programing language.
In Rspec, if we want only compare value of two object. we can use eq
method. In this case, we can rewrite as:
Then we can pass the test:
3. Multiples of 5 should be Buzz
The logic of the previous step’s procedures we did that was same as the this step’s what we do. I only post my code.
Unit test(spec/models/fizz_buzz_spec.rb):
FizzBuzz.to_Buzz
method:
rspec
result:
4. Multiple of 15 should be FizzBuzz, and check every element of the final answer is correct.
This is the last part of FizzBuzz: Turn multiples of 15 to FizzBuzz. It’s test is too similar with past two. So I will jump to the last test. Check three function will run write when they run together.
This is not only a Unit Test but like a Integration Test. I can be sure that my FizzBuzz
model can do things right as I wish. If multiples of 3, 5 or 15 return right value and other numbers return itself. My development will be done.
The final test would like this:
In the end of article, wish you can give me some claps.
Thanks for your generous.