Reputation: 421
I'm very stuck when it comes to writing a test to check if an instance variable equals a certain value then it should call a certain method, and that if it is less than that value, then it should not. I have an instance variable, @counter, which is initialized at 0, and these methods:
def increment_counter
@counter += 1
if @counter == 9
tie_game?
end
end
def tie_game?
puts "The game was a tie. Nicely played #{@player1} & #{@player2}!"
play_again
end
I want to write a test to check that when @counter equals 9, that tie_game? is called, and that when it is less than 9, it is not called.
This is what I could come up with, but it is wrong:
describe "increment_counter" do
context "counter equals 9" do
it "calls tie_game?" do
game.instance_variable_set(:@counter, 9)
expect(increment_counter).to receive(:tie_game?)
end
end
end
Upvotes: 2
Views: 5865
Reputation: 11905
You should check whether tie_game?
was called on the game
instance and not on increment_counter
. With the code you have given, one way to do this would be
describe "increment_counter" do
context 'counter equals 9' do
let(:game) { Game.new }
it 'calls tie_game?' do
game.instance_variable_set(:@counter, 8)
game.increment_counter
expect(game).to receive(:tie_game?)
end
it 'does not call tie_game?' do
game.increment_counter
expect(game).not_to receive(:tie_game?)
end
end
end
I am assuming that your class name is Game
. Since both your examples require a game
instance, we can dry it up and use let
to define the game instance. Note that let
is lazily evaluated
. Meaning its only executed when its referenced in the example block. If you set your instance variable to 0 in the initialize
method, the tests will work fine.
Note that I am setting @counter
to 8 and then I am triggering increment_counter
method to test whether it calls tie_game?
PS: Should tie_game
be a boolean method? Does play_again
return a boolean.I am not sure if it should be a boolean method.
Upvotes: 3