如何在rspec中测试put

Jes*_*ssi 28 rspec

我想做的是ruby sayhello.rb在命令行上运行,然后接收Hello from Rspec.

我有这个:

class Hello
  def speak
    puts 'Hello from RSpec'
  end
end

hi = Hello.new #brings my object into existence
hi.speak
Run Code Online (Sandbox Code Playgroud)

现在我想在rspec中编写一个测试来检查命令行输出实际上是"来自RSpec的Hello"而不是"我喜欢Unix"

不工作.我目前在sayhello_spec.rb文件中有这个

require_relative 'sayhello.rb' #points to file so I can 'see' it

describe "sayhello.rb" do
  it "should say 'Hello from Rspec' when ran" do        
    STDOUT.should_receive(:puts).with('Hello from RSpec')    
  end
end
Run Code Online (Sandbox Code Playgroud)

另外,我需要实际看看我的RSPEC中的测试应该是什么样子.

Art*_*cki 19

我认为最好的方法是在输出匹配器中使用rspec build https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/output-matcher

例如,这是你的班级

class MakeIt
  def awesome(text)
    puts "Awesome #{text}"
  end
end
Run Code Online (Sandbox Code Playgroud)

和你的考试

describe MakeIt do
  describe '#awesome' do
    it 'prints awesome things' do
      expect do
        MakeIt.new.awesome('tests')
      end.to output('Awesome tests').to_stdout
    end

    it 'does not print not awesome things' do
      expect do
        MakeIt.new.awesome('tests')
      end.to_not output('Not awesome tests').to_stdout
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

很好,很干净,靠书!

  • 您知道是否有任何方法可以使用 contains 而不是完全相同的方法来做到这一点? (2认同)
  • @AlexandreAmadodeCastro 有点晚了,但你可以使用 `expect(...).to output(a_string_include('xxx')).to_stdout` 参见[此备忘单](https://gist.github.com/JunichiIto/f603d3fbfcf99b914f86 ) (2认同)

Pet*_*vin 16

您在进入测试块之前执行代码,因此未达到预期.您需要在设置期望后运行测试块中的代码(例如,通过在require_relative语句后移动STDOUT....语句),如下所示:

describe "sayhello.rb" do
  it "should say 'Hello from Rspec' when ran" do        
    STDOUT.should_receive(:puts).with('Hello from RSpec')
    require_relative 'sayhello.rb' #load/run the file 
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这与新的RSpec语法的期望相同:`expect(STDOUT).to receive(:puts).with("来自RSpec的Hello") (5认同)

Dan*_*Dan 15

根据以前的答案/评论,使用没有gem的新语法的解决方案将如下所示:

describe "sayhello.rb" do
  it "should say 'Hello from Rspec' when run" do        
    expect(STDOUT).to receive(:puts).with('Hello from RSpec')
    require_relative 'sayhello.rb'  # load/run the file 
  end
end
Run Code Online (Sandbox Code Playgroud)


bsw*_*ton 12

您可以使用Rails的active_support库解决此问题,该库添加了一个capture方法:

require 'active_support/core_ext/kernel/reporting'
require_relative 'sayhello'

describe Hello do
  it "says 'Hello from RSpec' when ran" do
    output = capture(:stdout) do
      hi = Hello.new
      hi.speak
    end
    expect(output).to include 'Hello from RSpec'
  end
end
Run Code Online (Sandbox Code Playgroud)

  • "#capture"已被弃用,将在Rails 5中删除.https://github.com/rails/rails/blob/dd7bd8c023696657a600ee5dba16bfe5def876bf/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L91 (11认同)