Stubbing chain of methods with arguments

1,498 views
Skip to first unread message

siva

unread,
Feb 4, 2014, 4:05:12 AM2/4/14
to rs...@googlegroups.com


   Hi all

   In my controller I have code as below:

      # app/controllers/bookings_controller.rb

     @booking.unit_installments.each do |i|
        InterestAmount.new(i, Date.today, project).calculate
      end

     I have seen `stub_chain` method but I didn't find how to stub chain methods with arguments and how to verify chain methods with arguments as well. Could you help me?

    Thanks in advance.

Xavier Shay

unread,
Feb 5, 2014, 12:12:44 AM2/5/14
to rs...@googlegroups.com
What are you trying to test/assert here?
At a first glance, I'd refactor InterestAmount to provide an interface
`InterestAmount.calculate`, then you don't need to use stub_chain, and
also hide your implementation.

Cheers,
Xavier
>
> Thanks in advance.
> --
> You received this message because you are subscribed to the Google
> Groups "rspec" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to rspec+un...@googlegroups.com.
> To post to this group, send email to rs...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rspec/be2b852e-283d-4d80-99c3-c83604aa9513%40googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

siva

unread,
Feb 6, 2014, 1:40:49 AM2/6/14
to rs...@googlegroups.com

  Hi Xavier

   Thanks for your reply.

   I want assert whether `calculate` has been called no. of times that loop has been iterated with the same parameters every time.

  And on class `InterestAmount` initializer I set the parameters in instance variables like as  follows so that I can use same instance variables across all methods in `InterestAmount` class.

  class InterestAmount
   def initialize(installment, date, project)
    @installment = installment
    @project = project
    @date = date
  end
  end

Xavier Shay

unread,
Feb 6, 2014, 10:25:28 PM2/6/14
to rs...@googlegroups.com

On 5/02/14 10:40 PM, siva wrote:

  Hi Xavier

   Thanks for your reply.

   I want assert whether `calculate` has been called no. of times that loop has been iterated with the same parameters every time.

  And on class `InterestAmount` initializer I set the parameters in instance variables like as  follows so that I can use same instance variables across all methods in `InterestAmount` class.

  class InterestAmount
   def initialize(installment, date, project)
    @installment = installment
    @project = project
    @date = date
  end
  end
If you do:

class InterestAmount
  def self.calculate(*args); new(*args).calculate; end
  #...
end

you hide the initializer, and subsequently your tests get much nicer. (i.e. listening to the test leads to a nicer interface)

siva

unread,
Feb 9, 2014, 9:40:13 AM2/9/14
to rs...@googlegroups.com

 
 Thanks Xavier it worked. But I need a small clarification. How could we stub chain of methods where each method asks a set of arguments?

Myron Marston

unread,
Feb 16, 2014, 10:20:00 AM2/16/14
to rs...@googlegroups.com
You can stub any arbitrary chain of methods by setting up the stubs individually:

allow(a).to receive(:foo).with(1).and_return(b = double)
allow(b).to receive(:bar).with(2).and_return(c = double)
allow(c).to receive(:baz).with(3).and_return("it worked")

expect(a.foo(1).bar(2).baz(3)).to eq("it worked")

HTH,
Myron

Arup Rakshit

unread,
Jan 1, 2015, 9:37:47 AM1/1/15
to rs...@googlegroups.com

You can stub any arbitrary chain of methods by setting up the stubs individually:

allow(a).to receive(:foo).with(1).and_return(b = double)
allow(b).to receive(:bar).with(2).and_return(c = double)
allow(c).to receive(:baz).with(3).and_return("it worked")

expect(a.foo(1).bar(2).baz(3)).to eq("it worked")

HTH,
Myron

Myron,

Is this accepted answer is wrong approach to the problem as given ? http://stackoverflow.com/a/8522108/2767755 

Myron Marston

unread,
Jan 1, 2015, 3:04:42 PM1/1/15
to rs...@googlegroups.com
That answer is fine.  It's equivalent to what I posted above, but using the older syntax (`stub`) rather than the newer `allow` syntax, and also using blocks for return values rather than `and_return`. 
Reply all
Reply to author
Forward
0 new messages