TDD Beyond Basics : Dependency Inversion Principle - Guessing Game Kata Part 3


  • Learn about Dependency Inversion Principle


Refer the guessing game problem description described in the first part of this series on guessing game : TDD Beyond Basics : Testing Random Behavior.

In the previous article you learned the Single Purpose Principle. The spec used a mock that complies with Gerard Meszaros standard discussed in his book xUnit Test Patterns: Refactoring Test Code. We followed that standard. We used double and set expectation, so it is a mock. If we don't set the expectation on the double, it can be used as a stub. In this article we will continue working on the guessing game.


Step 1

Let's take our code for a test drive. From the directory where the guess_game.rb resides, run the following code in irb:

load './guess_game.rb'

game =

This gives us the error:

NoMethodError: undefined method 'output' for

Step 2

Run the following code in irb:

STDOUT.puts 'hi'

It will print 'hi' on the standard output.

Step 3

But it does not recognize output(string) method. To fix this problem, let's wrap the output method in a StandardOutput class. Create standard_output.rb with the following contents:

class StandardOutput
  def output(message)
    puts message

Step 4

Change the constructor of the GuessGame like this:

class GuessGame
  def initialize(
    @console = console

Step 5

The StandardOutput class in not a built-in Ruby class. It's our custom class.

irb > Kernel
  => Kernel
irb > StandardOutput
  NameError: uninitialized constant Object::StandardOutput
    from (irb):2

You can quickly double check this by searching the [Ruby documentation]: . We do this check to avoid inadvertently reopening an existing class in Ruby.

Step 6

The current version of specs look like this:

require_relative 'guess_game'

describe GuessGame do
  it 'generates random number between 1 and 100 inclusive' do
    game =
    result = game.random

    expected = 1..100
    expected.should cover(result)

  it 'displays greeting when the game begins' do
    fake_console = double('Console')
    fake_console.should_receive(:output).with('Welcome to the Guessing Game')
    game =

This is version that we ended up in the previous article. We have not made any changes to it yet. Run the specs, the tests still pass.


This fix shows how to invert dependencies on concrete classes to abstract interface. In this case the abstract interface is 'output' and not specific method like 'puts' or GUI related method that ties the game logic to a concrete implementation of user interaction.

Step 7

Change the guess_game.rb constructor default value as follows:

  def initialize(
    @console = console

The complete guess_game.rb now looks like this:

class GuessGame
  def initialize(
    @console = console

  def random

  def start
    @console.output('Welcome to the Guessing Game')

In this version we fixed the bug due to wrong default value in the constructor.


In this article we saw Dependency Inversion Principle. We learned how to invert dependencies so that we depend on abstractions instead of concrete classes. Our code will be brittle if we depend on concrete classes. In the next article you will learn about using null objects in specs.

Related Articles

Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.