Reputation: 142
I am doing a command line of game of Rock Paper Scissors Lizard Spock in Ruby. I have the matchup
method that takes the variables @shape
(the hand shape randomly selected by the game) and @player_shape
(the hand shape chosen by the player).
My matchup
method compares the two shapes and sets the game result to @result
:
class Game
SHAPES = [:rock, :paper, :scissors, :lizard, :spock]
attr_reader :shape, :player_shape, :status
# ...
def matchup
if @shape == @player_shape
@result = :draw
else
case @player_shape
when :rock
@result = (@shape == :scissors || @shape == :lizard) ? :player_wins : :game_wins
when :paper
@result = (@shape == :rock || @shape == :spock) ? :player_wins : :game_wins
when :scissors
@result = (@shape == :paper || @shape == :lizard) ? :player_wins : :game_wins
when :lizard
@result = (@shape == :paper || @shape == :spock) ? :player_wins : :game_wins
when :spock
@result = (@shape == :rock || @shape == :scissors) ? :player_wins : :game_wins
end
end
end
# ...
end
I ran the code many times and it works as expected, but in my spec file, the result I'm getting is not matching the code behavior. Here is the spec:
describe Game do
subject(:game) { Game.new }
# ...
describe "#matchup" do
context "game chooses rock" do
before do
allow(game).to receive(:shape).and_return(:rock)
end
it "sets result as :player_wins if the game chooses paper" do
allow(game).to receive(:player_shape).and_return(:paper)
game.matchup
expect(game.result).to eq(:player_wins)
end
end
end
end
and here is the result:
Failure/Error: expect(game.result).to eq(:player_wins)
expected: :player_wins
got: :draw
(compared using ==)
Diff:
@@ -1,2 +1,2 @@
-:player_wins
+:draw
What I am doing wrong here? I've tried and tried and still can't figure out how to solve this problem.
Upvotes: 0
Views: 61
Reputation: 5929
Here
allow(game).to receive(:shape).and_return(:rock)
and there
allow(game).to receive(:player_shape).and_return(:paper)
You're stubbing methods Game#shape
and Game#player_shape
for game
object.
But you're using @shape == @player_shape
as condition in if
statement.
Ruby treats undefined instance variables (those which starts from @
) as nil
by default.
→ irb
irb(main):001:0> @shape
=> nil
Thus @shape == @player_shape
is the same as nil == nil
in your case. Which is actually a true
. What's why program flow reach @result = :draw
line.
To make it work you need to define shape
and player_shape
methods by using attr_reader, for example, and use them instead of instance variables.
upd
Now replace @shape
with shape
and @player_shape
with player_shape
in your code. Be sure you initialise values for them.
Take a look at that Ruby Monk tutorial (or any other articles) about instance vairables to understand how they work
Upvotes: 2