Rspec TDD Kata: FizzBuzz

Roger Wang
6 min readJun 8, 2018

--

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.

  1. Do not write any production code without a failing test first.
  2. Write only enough test code as is sufficient enough to fail.
  3. 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.

BAD test name
Good test 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:

--

--

No responses yet