测试文件和测试文件相互通信

时间:2015-02-05 21:34:38

标签: ruby rspec rspec3

我正在学习Ruby和RSpec,而且我遇到了一个障碍,其中大多数可用的学习材料已被弃用,我缺乏筛选残骸的词汇。

class Session

  def initialize(winning_score = 0)
    @winning_score = winning_score
    play
  end

  def play
    get_players
    max_score
    while #game is in play
      print_score
      #play game
    end
    winner
  end

  def get_players
    puts "\nPlayer X name:"
    p1 = gets.chomp.upcase
    @player1 = Player.new(p1, "X", 0)
    puts "\nPlayer O name:"
    p2 = gets.chomp.upcase
    @player2 = Player.new(p2, "O", 0)
  end

  def max_score
    puts "\nBest out of how many?"
    max = gets.chomp
    @winning_score = (max.to_f/2).ceil
  end

  def print_score
    puts "\n#{@player1.name}: #{@player1.score} \n#{@player2.name}: #{@player2.score}"
  end

  def winner
    if @player1.score == @winning_score
        puts "\n#{@player1.name} WINS!!!"
    elsif @player2.score == @winning_score
        puts "\n#{@player2.name} WINS!!!"
    end
  end
end

class Player

  attr_accessor :name, :mark, :score

  def initialize(name, mark, score)
    @name = name
    @mark = mark
    @score = score
  end

end

RPEC:

describe "Play" do

  before(:each) do 
    allow(x).to receive(:puts)
    allow(x).to receive(:print)
  end

  let(:x) { Session.new }

  it "displays game score" do
    @player1 = Player.new("p1", "X", 0)
    @player2 = Player.new("p2", "O", 2)
    expect(x).to receive(:puts).with("\np1: 0 \np2: 2")
    x.print_score
    x.play
  end
end

...我认为这是所有适用的代码......问题是正在测试的文件和RSpec文件一直在相互讨论,我不断得到这样的东西:

1) play displays game score
 Failure/Error: expect(x).to receive(:puts).with("\np1: 0 \np2: 2")
   #<Session:0x007fc16b9f5d38> received :puts with unexpected arguments
     expected: ("\np1: 0 \np2: 2")
          got: ("\n\t\t: 0 \n\tEND: 0"), ("\nPlayer X name:"), ("\nPlayer O name:"), ("\nBest out of how many?"), ("\n\tIT \"GETS AND CREATES PLAYERS\" DO WINS!!!")
 # ./tictactoe_spec.rb:36:in `block (2 levels) in <top (required)>'

...噪音是其他方法得到的地方。运行RSpec代码并将其存储为播放器名称...我无法弄清楚如何防止这种情况发生,清除/重置它,或者是什么正确的行动方案甚至是......请告知。

2 个答案:

答案 0 :(得分:0)

嗯,您正在测试上下文中设置@player1@player2个实例变量。虽然你在会话对象中需要它们。

我认为这里的一个好方法是存根get_players方法,但我们将不得不改变它。

class Session

  #...

  def get_players
    @player1 = get_player("X")
    @player2 = get_player("O")
  end

  def get_player(mark)
    puts "\nPlayer #{mark} name:"
    name = gets.chomp.upcase
    Player.new(name, mark, 0)
  end

  #...

end

现在你可以存根那些get_player调用

  # ...

  it "displays game score" do
    allow(x).to recive(:get_player).with("X") { Player.new("p1", "X", 0) }
    allow(x).to recive(:get_player).with("O") { Player.new("p2", "O", 2) }

    expect(x).to receive(:puts).with("\np1: 0 \np2: 2")
    x.print_score
    x.play
  end

答案 1 :(得分:0)

解决方案是在初始化时实现一个可选的输出源,默认为stdout,然后为要放入的方法创建一个输出源的double。在与一些经验丰富的开发者交谈之后,这似乎是一件相当普遍的事情。稍微简化代码可能也会非常有用......回顾它是非常糟糕的。