2016-07-14 116 views
1

我無法弄清楚如何編寫一個可以工作的測試,它也不會在CL中的腳本中運行任何東西。當@counter是9時,它應該觸發#tie_game?但它不起作用。 @counter初始化爲0,並且每次玩家在遊戲板上放置一個X或一個O時增加1。我如何測試一次@counter是9,它稱爲tie_game?而當它小於9時,它不會?rspec測試如果方法被調用

def initialize(player1, player2) 
    @player1 = player1 
    @player2 = player2 
    @rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

    @wins = [1, 2, 3], [4, 5, 6], [7, 8, 9], 
     [1, 4, 7], [2, 5, 8], [3, 6, 9], 
     [1, 5, 9], [3, 5, 7] 

    @selected_numbers = [] 
    @counter = 0 
end 

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 

我試過這個:你能解釋它爲什麼不起作用嗎?

describe "increment_counter" do 
    context "counter equals 9" do 
     it "calls tie_game?" do 
      game.instance_variable_set(:@counter, 9) 
      allow(game).to receive(:increment_counter) 
      #expect(STDOUT).to receive(:puts).with("The game was a tie. Nicely played #{@player1} & #{@player2}!") 
      expect(game).to receive(:tie_game?) 
     end 
    end 
    context "counter is less than 9" do 
     it "does not call tie_game?" do 
      game.instance_variable_set(:@counter, 4) 
      game.increment_counter 
      expect(game).not_to receive(:tie_game?) 
     end 
    end 
end 
+0

我發佈我的答案後,我看到了您的編輯。它沒有爲你工作的原因是你在設定期望之後永遠不會實際調用你的代碼。在測試是否發送和接收消息時,您必須反轉期望/運行順序。 – JasonK

+0

好的真棒。非常感謝您的幫助,這肯定更有意義 –

回答

3

的RSpec嘲笑爲你做這個。

describe TicTacToe do 
    let(:game) { TicTacToe.new } 

    context "after fewer than 9 moves" do 
    it "does not call tie_game?" do 
     expect(game).not_to receive(:tie_game?) 
     8.times { game.increment_counter } 
    end 
    end 

    context "after 9 moves" do 
    it "calls tie_game?" do 
     expect(game).to receive(:tie_game?) 
     9.times { game.increment_counter } 
    end 
    end 
end 

有關更多詳細信息,請參見https://relishapp.com/rspec/rspec-mocks/v/3-5/docs/basics/expecting-messages

作爲一個側面說明,tie_game?可能在它後面不應該有問號。 tie_game?表明它正在檢查遊戲是否被綁定。

+0

非常感謝您爲此,我可以因此刪除大量代碼。 –

+0

注意,你不能使用沒有雙打的'have_received'。你必須像這個例子那樣測試'receive'。 –

0

這是一個有趣的問題。我的做法是猴子修補課程,重新定義方法tie_game?,這會產生一些可以通過測試檢測到的副作用。

由於我沒有看到您的班級名稱,我們只需將其稱爲Foo

首先,創建一個模塊,說TrackMethods

module TrackMethods 
    # A global variable that stores how many times a method is called. 
    $method_calls = Hash.new(0) 

    def self.[](*method_names) 
    Module.new do 
     method_names.each do |name| 
     define_method name do |*args, &block| 
      $method_calls[name] += 1 
      super(*args, &block) 
     end 
     end 
    end 
    end 
end 

然後在spec_helper.rb

Foo.prepend TrackMethods[:tie_game?] 

之後,在您的測試,你可以

expect($method_calls[:tie_game?]).to be > 0 
+0

感謝您的回覆,我只是對我的OP進行了編輯 –

相關問題