ruby - How to test only one of the multiple method calls in RSpec? -


in method have multiple calls method different arguments. want test 1 particular call see if arguments call match condition. there better way stubbing every other call?

for example, have

def some_method   foo(1)   foo('a')   foo(bar) if ... # complex logic   foo(:x)   ... end 

i want test if foo called argument bar.

subject.should_receive(:foo).with(correct_value_of_bar) 

but other calls of foo inside same some_method?

okay, based on latest comment want observe you're logging output. here's example observe behavior replacing stdout stringio instance:

# foo.rb require 'rubygems' require 'rspec' require 'rspec/autorun'  require 'stringio'  class foo   def     puts 1     puts 'a'     puts 'bar' if true # complex logic     puts :x   end end   describe foo   describe '#something'     context "and complex happens"       let(:io){ stringio.new }       "logs stdout"         $stdout = io         foo.new.something         expect(io.tap(&:rewind).read).to include("bar\n")       end     end   end end 

this work, doing has side-effects reach far beyond specific example because we're changing global $stdout. can improved using poor man's dependency injection constructor defaults:

class foo   def initialize(io=stdout)     @io = io   end    def     puts 1     puts 'a'     puts 'bar' if true # complex logic     puts :x   end    protected    def puts(*args)     @io.puts *args   end end   describe foo   describe '#something'     context "and complex happens"       let(:io){ stringio.new }       "logs stdout"         foo.new(io).something         expect(io.tap(&:rewind).read).to include("bar\n")       end     end   end end 

in above example give ourselves ability pass in io object we'll putting to. lets observe behavior without having side-effects beyond scope of test , in way lets object we're testing stay true (ie: we're not modifying object previous deleted comment using as_null_object suggested).

you use options hash on constructor , push lazy assignment initialize itself:

def initialize(arg1, arg2, options={})    @io = options[:io] || stdout end  

and upgrade simple puts use actual logger object. test in 1 place logger worked stdout, stderr or ever , test in of objects cared logging logging info, debug, etc appropriately.

you take in few more directions well, without knowing more you're doing potential answer long enough.

hopefully gives ideas how approach observing behavior rather relying on internal implementation details (like fact you're using puts opposed print "bar\n" or method outputs text io object.


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -