ruby - How can I appropriately mock out a method that returns yield? -
it's common in ruby methods take blocks this:
class file def open(path, mode) perform_some_setup yield ensure do_some_teardown end end
it's idiomatic method this:
def frobnicate file.open('/path/to/something', 'r') |f| f.grep(/foo/).first end end
i want write spec doesn't hit filesystem, ensures pulls right word out of file, like:
describe 'frobnicate' 'returns first line containing substring foo' file.expects(:open).yields(stringio.new(<<eof)) not line foo bar baz not line either eof expect(frobnicate).to match(/foo bar baz/) end end
the problem here that, mocking out call file.open
, i've removed return value, means frobnicate
return nil
. if add file.returns('foo bar baz')
chain, however, i'd end test doesn't hit of code i'm interested in; contents of block in frobnicate
, test still pass.
how might appropriately test frobnicate
method without hitting filesystem? i'm not particularly attached particular testing framework, if answer "use awesome gem that'll you" i'm ok that.
it seems need mock call file
little differently. getting syntax errors running code as-is, i'm not sure version of rspec you're on, if you're on 3.x job:
frobnicate_spec.rb
gem 'rspec', '~> 3.4.0' require 'rspec/autorun' rspec.configure |config| config.mock_with :rspec end def frobnicate file.open('/path/to/something', 'r') |f| f.grep(/foo/).first end end rspec.describe 'frobnicate' 'returns first line containing substring foo' allow(file).to receive(:open).and_call_original allow(file).to receive(:open).and_yield stringio.new <<-eof not line foo bar baz not line either eof expect(frobnicate).to match(/foo bar baz/) end end
invoke ruby frobnicate_spec.rb
can use specified rspec version.
source: rspec mocks expecting messages , yielding responses
Comments
Post a Comment