RSpec的未定义方法`capture'

时间:2017-08-10 23:23:45

标签: ruby rspec

我正在尝试编写一个规范来测试显示井字游戏板。我正在使用方法capture但是在运行规范时会抛出错误。我正在使用捕获来获取方法调用的输出。 https://apidock.com/rails/Kernel/capture 这是我的方法:

  def display_board
    puts " #{grid[0]} | #{grid[1]} | #{grid[2]} "
    puts "-----------"
    puts " #{grid[3]} | #{grid[4]} | #{grid[5]} "
    puts "-----------"
    puts " #{grid[6]} | #{grid[7]} | #{grid[8]} "
  end

这是我的Rspec测试:

context "#display_board" do
     output = capture(:stdout) { board.display_board}
     rows = output.split("\n")
     binding.pry
     expect(rows[0]).to eq("   |   |   ")
     expect(rows[1]).to eq("-----------")
     expect(rows[2]).to eq("   |   |   ")
     expect(rows[3]).to eq("-----------")
     expect(rows[4]).to eq("   |   |   ")
  end

1 个答案:

答案 0 :(得分:1)

问题在于#capture已被弃用和删除。

就个人而言,我会将I / O与游戏内容的生成分开,因为它更容易使用并以此方式进行测试。因此,只需构建一个包含您的电路板的字符串(每行末尾有一个puts),而不是\n,并测试其是否正确。在实际游戏中,通过一次puts调用将电路板输出到控制台。

如果你真的想捕捉STDOUT,那就有办法了。 $stdout是一个全局,包含对当前STDOUT流的引用。默认情况下,此值始终设置为STDOUT,这是表示程序实际STDOUT的常量,但您可以将$stdout重定向到另一个IO流,例如StringIO对象。 puts将写入$stdout引用的任何内容,而不是直接写入STDOUT(这里有一个微妙的区别!)。

$stdout = StringIO.new
puts 'this is my output'
captured_output = $stdout.string
$stdout = STDOUT # restore it when you're done

现在你有了这是我的输出' ({1}}中捕获的(后跟换行符)。但是你在那个时候还有其他东西可以用于STDOUT,所以它并不理想(例如你的ruby控制台中的控制台输出)。您应该将其包装在一个确保它始终被恢复的方法中,例如

captured_output

您可以将其与块一起使用,例如

def capture() 
  $stdout = StringIO.new
  yield
  $stdout.string
ensure
  $stdout = STDOUT
end

(但是如果你忘记了这种方法并且只是将你的电路板建成一个字符串,那么你将拥有更轻松的生活。)