コンソールにいくつかのメッセージを表示するクラスをテストしています (puts、p 警告など)。RSpec テスト中にこの出力を抑制する機能があるかどうか疑問に思っています。
8 に答える
テキスト ファイルに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
編集:
@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
それは少しきれいに見え、メソッドをmain
. また、Ruby 2.0 を使用している場合は、__dir__
代わりにFile.dirname(__FILE__)
.
EDIT2
また、Ruby v 1.9.3 で導入されたもの/dev/null
を使用して、真の OS に転送できることにも言及する必要があります。File::NULL
(jruby1.7)
次に、コード スニペットは次のようになります。
#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
beforeブロックで出力を行うスタブメソッドを試してください。
before do
IO.any_instance.stub(:puts) # globally
YourClass.any_instance.stub(:puts) # or for just one class
end
これは明示的であるため、見逃したくないものを見逃すことはありません。出力を気にせず、上記の方法が機能しない場合は、いつでもIOオブジェクト自体をスタブできます。
before do
$stdout.stub(:write) # and/or $stderr if needed
end
単一のテストの出力を抑制したい場合は、より簡潔な方法があります。
it "should do something with printing" do silence_stream(STDOUT) do foo.print.should be_true end end
テストでエラーが出力される場合は、に変更することをお勧めしSTDOUT
ます。STDERR
STDOUT をデフォルトとする IO オブジェクトを注入すると便利な場合があります。これにより、必要に応じて出力でアサートすることも容易になります。
例えば
def my_method(arg, io: STDOUT)
io.puts "hello"
arg.reverse
end
そして、あなたのテストで:
# Suppress it.
my_method("hi", io: StringIO.new)
# Assert on it.
io = StringIO.new
my_method("hi", io: io)
output = io.tap(&:rewind).read
expect(output).to include("hello")