2012-10-18 67 views
1

我将此方法作为更大类的一部分。我试图为它写一个测试,但是我对rspec很陌生,而且我有点难倒...如果我在9.times循环中注释掉所有内容,我可以测试'drawgrid'。但如果我取消注释该代码,则当前测试失败。我需要测试游戏方法......来运行游戏。它把'drawgrid'...运行游戏序列9次,每次回合后放置'drawgrid'。但我不知道如何做到这一点。任何指针都非常感谢。如何为一种方法编写rspec测试

下面是游戏方法,它是当前规范

 def play 
     #draw the board 
     puts drawgrid 

     #make a move 
     turn = 0 

     9.times do 

      if turn.even? 

      @player = @player_h.move_human("X", @board) 

      @move = @player.to_sym 
      @marker = @player_h.boardpiece 

      does_move_exist(@move,@marker) 
      is_a_human_win(@board) 

      else 

      @player = @player_c.move_computer("O", @board) 

      @move = @player 
      @marker = @player_c.boardpiece 

      does_move_exist(@move,@marker) 
      is_a_computer_win(@board) 

      end 

      puts drawgrid 

      turn += 1 
     end # 9.times ends 
     end 

电流规格....

 describe 'play method' do 
     it 'draws the game grid' do 
      @player_human = Player.new('X') 
      @player_computer = Player.new('O') 
      @board = Board.new 
      @game = Game.new(@player_human, @player_computer, @board) 

      @game.should_receive(:puts).with("\na | | \n----------\nb | | \n----------\nc | | \n----------\n 1 2 3\n") 

      @game.play 
     end 
     end 
     describe '9.times' do 
     it 'runs game sequence 9 times...once per board spot' do 
      @player_human2 = Player.new('X') 
      @player_computer2 = Player.new('O') 
      @board2 = Board.new 
      @game2 = Game.new(@player_human2, @player_computer2, @board2) 

      turn = 0  
      9.times do 
      if turn.even? 
       @player_human2.should_receive(:puts).with("human move...") 
       @player_human2.stub(:gets).and_return("b2") 
      else 
       @player_human2.should_receive(:puts).with("computer move...") 
       @player_human2.stub(:gets).and_return("a1") 
      end 
      turn += 1 
      end 
     @game2.play 
     end 
     end 
+0

另外根据Dave Giunta在他的回答中所说的话,我强烈建议阅读[RSpec Book]的第一部分(http://pragprog.com/book/achbd/the-rspec-book),标题为“RSpec&Cucumber入门'。在这9章中,本书让读者通过构建数字猜测游戏的练习,并说明如何使用规范和功能编写易于维护的代码。 –

+0

感谢您的回复。我现在已经和我一起阅读了这篇文章......你知道那个地方,在你阅读完路径之后,你会尝试走这条路吗?那就是我现在的地方。试图让我的大脑和我的手指“理解”。我有这个文本以及在github上列出的信息... https://github.com/rspec/rspec-expectations和... https://github.com/rspec/rspec-mocks...使用as参考资料... sooo多读书总是:) – thefonso

回答

3

一般情况下,我觉得您的代码以及测试正在尝试做的太一种方法很多。关于你的玩法的有趣之处不在于那个循环内部发生的9次。我对重构的第一个建议是将该循环内部的内容转换为名为“take_turn”或类似的方法。

然后,您可以编写规格说明单回合会发生什么。而且,对于play方法的规范将测试take_turn方法被调用9次。

这并不是说你不能保持你的代码的方式,并为它写一个有效的测试...你不能超级外科关于你正在测试的东西。

希望有所帮助。

+0

是的....大YES。我怀疑我的方法太多了。我被困在...试图与rspec战斗或简化这种方法...你刚刚证实了我...在简化。 – thefonso

3

我是第二个什么戴夫说。尽量简化。基本上,如果你可以简化你的玩法,它会简化你的测试。现在游戏关注每一回合的实施细节。把这些细节推下来,你的测试可以变得更容易编写和更细化。我不是最好的,我不是这个超级幸福了,但希望下面的代码推你在正确的方向:

#play.rb 

class Board 
end 

class Player 
    def initialize(symbol) 
    @symbol = symbol 
    end 

    def take_turn 
    end 
end 

class Game 
    def initialize(player1, player2, board) 
    @player1, @player2, @board = player1, player2, board 
    end 

    def play 
    drawgrid 

    (0...9).each do |turn| 
     turn.even? ? @player1.take_turn : @player2.take_turn 
     drawgrid 
    end 
    end 

    def drawgrid 
    end 
end 

而且测试文件:

#play_spec.rb 
require './play.rb' 

describe '#play' do 
    before do 
    @player1 = Player.new('X') 
    @player2 = Player.new('O') 
    @game = Game.new(@player1, @player2, Board.new) 
    end 

    it 'draws the game grid' do 
    @game.should_receive(:drawgrid).at_least(:once) 
    @game.play 
    end 

    it 'runs game sequence 9 times...once per board spot' do 
    @player1.stub(take_turn: true) 
    @player2.stub(take_turn: true) 
    @player1.should_receive(:take_turn).exactly(5).times 
    @player2.should_receive(:take_turn).exactly(4).times 
    @game.play 
    end 
end 
+0

谢谢你,先生。 – thefonso

+0

你的回答很可爱。我特别喜欢这个转向。全部在一条线上。我认为戴夫是第一个,但这也很棒。谢谢。 – thefonso