Wednesday, July 30, 2014

Week of RSpec

This week I've been spending some more time learning RSpec and writing the Connect Four game using TDD approach. While I am not done with the game yet (as of today), I already see that TDD approach forces me to write smaller and more compact methods, aimed at solving one and only task.

I would like to discuss one interesting way that I discovered of accessing variables initiated in an instance of another class. Say, my Connect Four game is very simple and consists of two classes:

class Board
end

class Game

  def initialize
    @board = Board.new
  end

end

I want to test that the Game properly initializes an empty Board. But how to access the Board? One of the options is to make Board visible to the outer world via getters and setters like so:

class Game
   
   attr_accessor :board

   def initialize 
     @board = Board.new
   end

end

In RSpec, one would then write a test like this:

describe "Game": 
  
  let (:game) { Game.new }
  
  it "initializes an empty board" do
    expect(game.board).to be_an_instance_of Board
  end

end

However, there may be situations when it is not desired to expose an object or a variable in this manner. I found the method instance_variable_get(:@your_object) to be useful. Our test can look like so:

describe "Game" do

  let (:game) { Game.new }

  it "initializes an empty board" do
    expect(game.instance_variable_get(:@board)).to be_an_instance_of Board
  end

end 

I realize this may not be the best design decision, as it is possible to wrap a variable you want to test in a method, and then call that method instead, which will return the value. However, it is good to know all available options.

No comments :

Post a Comment