Your two expectations need to be treated as separate things. First, as you noticed, abort
is now stubbed and therefore doesn't actually abort execution of your code -- it's really just acting like a puts
statement now. Because of this, abort is being called twice: once with your expected message, and then again within your begin
block. And if you add { abort }
to the end of your expectation, it will actually abort, but that will also abort your test suite.
What you should do is use a lambda and make sure the abort
is called:
lambda { Rgc::Init.new({}, {}, []) }.should raise_error SystemExit
abort
prints the message you give it to stderr. To capture that, you can add a helper to temporarily replace stderr with a StringIO
object, which you can then check the contents of:
def capture_stderr(&block)
original_stderr = $stderr
$stderr = fake = StringIO.new
begin
yield
ensure
$stderr = original_stderr
end
fake.string
end
it 'should abort when no key file given' do
stderr = capture_stderr do
lambda { Rgc::Init.new({}, {}, []) }.should raise_error SystemExit
end
stderr.should == "Key file must be given!\n"
end
(Credit to https://stackoverflow.com/a/11349621/424300 for the stderr replacement)