ruby 在 RSpec 测试期间抑制控制台输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15430551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Suppress console output during RSpec tests
提问by demas
I am testing the class which put on the console some messages (with puts, p warnings and etc.). I am just wondering if there is any ability to suppress this output during RSpec tests ?
我正在测试在控制台上放置一些消息的类(带有放置、p 警告等)。我只是想知道在 RSpec 测试期间是否有任何能力抑制此输出?
采纳答案by Charles Caldwell
I suppress putsoutput in my classes by redirecting $stoutto a text file. That way, if I need to see the output for any reason, it is there but it doesn't muddy up my test results.
我puts通过重定向$stout到文本文件来抑制我的类中的输出。这样,如果我出于任何原因需要查看输出,它就在那里,但不会混淆我的测试结果。
#spec_helper.rb
RSpec.configure do |config|
config.before(:all, &:silence_output)
config.after(:all, &:enable_output)
end
public
# Redirects stderr and stout to /dev/null.txt
def silence_output
# Store the original stderr and stdout in order to restore them later
@original_stderr = $stderr
@original_stdout = $stdout
# Redirect stderr and stdout
$stderr = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
$stdout = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
end
# Replace stderr and stdout so anything else is output correctly
def enable_output
$stderr = @original_stderr
$stdout = @original_stdout
@original_stderr = nil
@original_stdout = nil
end
EDIT:
编辑:
In response to the comment by @MyronMarston, it probably would be smarter to just insert the methods directly into beforeand afteras blocks.
为了回应@MyronMarston 的评论,将方法直接插入before并after作为块插入可能会更聪明。
#spec_helper.rb
RSpec.configure do |config|
original_stderr = $stderr
original_stdout = $stdout
config.before(:all) do
# Redirect stderr and stdout
$stderr = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
$stdout = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
end
config.after(:all) do
$stderr = original_stderr
$stdout = original_stdout
end
end
It looks a little cleaner and keeps methods off of main.
Also, note that if you are using Ruby 2.0, you can use __dir__instead of File.dirname(__FILE__).
它看起来更干净一些并且保持方法关闭main。另外,请注意,如果您使用的是 Ruby 2.0,则可以使用__dir__代替File.dirname(__FILE__).
EDIT2
编辑2
Also it should be mentioned, that you can forward to true os /dev/nullby using File::NULLas it was introduced in Ruby v 1.9.3. (jruby 1.7)
还应该提到的是,您可以/dev/null使用File::NULLRuby v 1.9.3 中引入的方式转发到真正的操作系统。(jruby 1.7)
Then the code snippet will look as following:
然后代码片段将如下所示:
#spec_helper.rb
RSpec.configure do |config|
original_stderr = $stderr
original_stdout = $stdout
config.before(:all) do
# Redirect stderr and stdout
$stderr = File.open(File::NULL, "w")
$stdout = File.open(File::NULL, "w")
end
config.after(:all) do
$stderr = original_stderr
$stdout = original_stdout
end
end
回答by Micha? Kwiatkowski
Try stubbing methods that make the output in a before block, e.g.
尝试在 before 块中输出的存根方法,例如
before do
IO.any_instance.stub(:puts) # globally
YourClass.any_instance.stub(:puts) # or for just one class
end
This is explicit, so you won't miss anything you don't want to miss. If you don't care about any output and the method above doesn't work you can always stub the IO object itself:
这是明确的,所以你不会错过任何你不想错过的东西。如果您不关心任何输出并且上述方法不起作用,您可以随时存根 IO 对象本身:
before do
$stdout.stub(:write) # and/or $stderr if needed
end
回答by jaiks
An Rspec3.0 Version would be => in spec_helper.rb
Rspec3.0 版本将是 => 在 spec_helper.rb
RSpec.configure do |c|
c.before { allow($stdout).to receive(:puts) }
end
it will act as before(:each)
它将充当 before(:each)
but :each is default, so no need to write it explicitly
但是 :each 是默认值,因此无需明确编写
回答by lfender6445
Tested with rspec-core (~> 3.4.0)
使用 rspec-core (~> 3.4.0) 测试
In describe block you could do
在描述块中你可以做
# spec_helper.rb
def suppress_log_output
allow(STDOUT).to receive(:puts) # this disables puts
logger = double('Logger').as_null_object
allow(Logger).to receive(:new).and_return(logger)
end
# some_class_spec.rb
RSpec.describe SomeClass do
before do
suppress_log_output
end
end
This way you have the advantage of toggling log output for specific tests. Note, this will notsuppress rspec warnings, or messages from rspec.
通过这种方式,您可以为特定测试切换日志输出。请注意,这不会抑制 rspec 警告或来自 rspec 的消息。
Another way to disable warnings coming from gems:
另一种禁用来自 gems 的警告的方法:
add config.warnings = falseto spec_helper
添加config.warnings = false到 spec_helper
If you wanted to suppress only certain logger methods, like error, info, or warnyou could do
如果您只想抑制某些记录器方法,就像error, info, or warn您可以做的那样
allow_any_instance_of(Logger).to receive(:warn).and_return(nil)
allow_any_instance_of(Logger).to receive(:warn).and_return(nil)
To disable warnings coming from the rspec gem
禁用来自 rspec gem 的警告
allow(RSpec::Support).to receive(:warning_notifier).and_return(nil)
allow(RSpec::Support).to receive(:warning_notifier).and_return(nil)
but this is generally discouraged because it is meant as a way to let you know you are doing something smelly in your tests.
但这通常是不鼓励的,因为它旨在让您知道您在测试中做了一些有味道的事情。
回答by shock_one
If you want to suppress output for a single test, there is a more concise way:
如果要抑制单个测试的输出,有一种更简洁的方法:
it "should do something with printing" do silence_stream(STDOUT) do foo.print.should be_true end end
it "should do something with printing" do silence_stream(STDOUT) do foo.print.should be_true end end
You may want to change STDOUTto STDERRif your test prints an error.
如果您的测试打印错误,您可能需要更改STDOUT为STDERR。
回答by concept47
Updated answer for Rails 5, in a one-off situation:
在一次性情况下更新了 Rails 5 的答案:
before do
RSpec::Mocks.with_temporary_scope do
allow(STDOUT).to receive(:puts)
end
end
You can make this into a method in spec_helper if you'll be doing this a lot.
如果你经常这样做,你可以把它变成 spec_helper 中的一个方法。
回答by Chris Hough
After trying all of these examples, I ended up using this varation which does not silence or mute binding.pry
在尝试了所有这些示例之后,我最终使用了这个不会使 binding.pry 静音或静音的变体
# frozen_string_literal: true
RSpec.configure do |config|
config.before(:each) do
allow($stdout).to receive(:puts)
allow($stdout).to receive(:write)
end
end

