为了清晰起见,将相关的代码片段从我的项目提取到一个小的独立测试模块......
require "stringio"
@output = $stdout
$buffer = StringIO.new
$stdout = $buffer
@output.puts "puts method to buffer text"
$stdout = STDOUT
$buffer.rewind
puts "buffer contents: #{$buffer.read}"
运行此代码,返回一个空缓冲区。我必须使用@ output.puts传递一个rspec @output(:puts)should_receive rspec测试。如果我用简单的“puts”替换@ output.puts,则填充缓冲区但rspec测试失败。
我已经搜索了几个小时的在线红宝石资源,并且不能使用任何内容来回答这个问题。任何帮助都感激不尽。
答案 0 :(得分:0)
试试这个:
require 'stringio'
def read_stdout(&block)
tmp = $stdout
$stdout = tmp = StringIO.new
block.call
tmp.string
ensure
$stdout = tmp # ensures that always evaluated
end
答案 1 :(得分:0)
行。最后的简单错误。
首先,插入
$buffer.write
行意味着我实际上是在写缓冲区,所以它不是空的!
其次,
@output.puts("string")
实际上并没有将字符串内容分配给@output,只是将它用作输出通道所以
$buffer.write(@output)
只是将十六进制字符而不是我的字符串写入缓冲区。
所以我必须明确地写字符串或将其分配给变量,即
@output="string"
$buffer.write(@output)
将字符串写入缓冲区。
感谢所有回应,这些回应让我以正确的方式 - 向前和向上 - 进行研究/思考。
答案 2 :(得分:-1)
你可以重新设计你的代码,不依赖于put并允许注入它写入的输出流,STDOUT是默认值,因此你的应用代码不必改变。
class Foo
def something_cool
puts "this is an artifact I want to test"
end
end
...变为
class Foo
def initialize(out=STDOUT)
@out = out
end
def something_cool
output "this is an artifact I want to test"
end
private
def output(msg)
@out.write("#{msg}\n")
end
end
你的考试变成......
out = StringIO.new
Foo.new(out)
Foo.something_cool
out.rewind.read.should eq("this is an artifact I want to test\n")