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

Test file and testing file talking through each other

我正在学习 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)>'

...噪音是其他方法 gets.chomping 运行 RSpec 代码并将其存储为玩家名称...我不知道如何防止这不会发生,clear/reset 它,或者甚至正确的行动方案是什么......请指教。

好吧,您正在测试上下文中设置 @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

解决方案是在初始化时实现一个默认为 stdout 的可选输出源,然后为要放入的方法创建该输出源的两倍。在与一些更有经验的开发人员交谈后,这似乎是一件相当普遍的事情。稍微简化代码也可能会非常有帮助……回头看这很糟糕。