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