rspec测试是否调用方法

时间:2016-07-14 14:23:17

标签: ruby testing rspec

我无法弄清楚如何编写一个可以正常运行的测试,也不会在我的脚本中运行CL中的任何内容。当@counter为9时,它应该触发#tie_game?但它不起作用。 @counter初始化为0,每当玩家在游戏板上放置X或O时,@counter会增加1。如果@counter为9,它如何调用tie_game?并且当它小于9时它不会?

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

2 个答案:

答案 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?建议它检查游戏是否绑定。

答案 1 :(得分: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