我在Ruby中使用Rock Paper Scissors Lizard Spock的游戏命令行。我有matchup
方法,它采用变量@shape
(游戏随机选择的手形)和@player_shape
(玩家选择的手形)。
我的matchup
方法比较两种形状并将游戏结果设置为@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
我多次运行代码并且按预期工作,但在我的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
以下是结果:
Failure/Error: expect(game.result).to eq(:player_wins)
expected: :player_wins
got: :draw
(compared using ==)
Diff:
@@ -1,2 +1,2 @@
-:player_wins
+:draw
我在这里做错了什么?我已经尝试过但仍然无法弄清楚如何解决这个问题。
答案 0 :(得分:2)
下面
allow(game).to receive(:shape).and_return(:rock)
然后
allow(game).to receive(:player_shape).and_return(:paper)
您为Game#shape
对象存储方法Game#player_shape
和game
。
但您在@shape == @player_shape
声明中使用if
作为条件。
Ruby默认将未定义的实例变量(从@
开始的变量)视为nil
。
→ irb
irb(main):001:0> @shape
=> nil
因此@shape == @player_shape
与您案例中的nil == nil
相同。实际上是true
。计划流程达到@result = :draw
行的原因是什么。
要使其工作,您需要使用attr_reader来定义shape
和player_shape
方法,例如,使用它们而不是实例变量。
<强> UPD 强>
现在将@shape
替换为shape
,将@player_shape
替换为代码中的player_shape
。确保初始化它们的值。
查看关于实例可变品的that Ruby Monk tutorial(或任何其他文章)以了解它们的工作原理