Domanda

I have following code:

class Init
  def initialize(global_options, options, args)
    abort "Key file must be given!" if (key_file = args.first).nil?

    begin
      @secret = File.read(key_file)
    rescue
      abort "Cannot read key file #{key_file}"
    end

    stdout, stderr, status = Open3.capture3("git status  -uno --porcelain")
    #...

and following specs for it:

describe Rgc::Init do
  context :initialize do
    it 'should abort when no key file given' do
      Rgc::Init.any_instance.should_receive(:abort)
        .with("Key file must be given!")

      Rgc::Init.new({}, {}, [])
    end
  end
end

And I get following output:

Failure/Error: Rgc::Init.new({}, {}, [])
#<Rgc::Init:0x0000000157f728> received :abort with unexpected arguments
expected: ("Key file must be given!")
got: ("Cannot read key file ")

should_receive method somehow block abort to take a place. How to fix the spec to check that app has been aborted and with specific message?

È stato utile?

Soluzione

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)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top