I want to do is run ruby sayhello.rb
on the command line, then receive Hello from Rspec
.
I\'ve got that with this:
class Hello
Somewhat similar to bswinnerton's answer, one can capture puts
output and then test against the captured output, without having to use the library-dependent capture
method (which someone has mentioned is being deprecated in Rails 5).
Ruby has a global variable named $stdout
which by default is populated by the constant STDOUT
. STDOUT
is that which sends data to the ruby process's stdout stream (not sure if "stream" is the right term here). Basically in a naive case STDOUT.puts("foo")
will result in "foo\n" appearing in your terminal window. $stdout.puts("foo")
will do the same thing because the $stdout
variable name refers to STDOUT
unless you reassign it (key point here). Finally puts("foo")
is syntactic sugar for $stdout.puts("foo")
.
The strategy then is to reassign $stdout
to a local IO
instance which you can inspect after running your code, to see if "Hello from RSpec" showed up in its contents.
How this would work:
describe "sayhello.rb" do
it "should say 'Hello from Rspec' when ran" do
$stdout = StringIO.new
# run the code
# (a little funky; would prefer Hello.new.speak here but only changing one thing at a time)
require_relative 'sayhello.rb'
$stdout.rewind # IOs act like a tape so we gotta rewind before we play it back
expect($stdout.gets.strip).to eq('Hello from Rspec')
end
end