On Thu, Apr 28, 2011 at 8:03 PM, Pat Maddox <patmad...@me.com> wrote:
> On Apr 28, 2011, at 4:37 PM, David Kahn wrote: > > > I am a bit new to mocking. I am trying to stub the > ActiveMerchant::Billing::PaypalGateway#authorize method but not clear how to > do it. This is my code and spec. > > > > This is the pertinent code: > > > > module Payment > > def gateway > > ActiveMerchant::Billing::PaypalGateway.new( > > ... > > ) > > end > > > > def authorize_payment(payment_info, associated_record_type, > associated_record_id) > > gateway.authorize(payment_info.amount ...... > > end > > > > I tried this: > > > ActiveMerchant::Billing::PaypalGateway.should_receive(:authorize).and_return(authorize_payment_success_response) > > This is setting an expectation on the PaypalGateway object (which is a > class!). But when you call PaypalGateway.new, you get back an instance - > which is where you want to set the expectation. So what you really need to > stub is something that looks more like an instance...you'd start off with: > > gateway = stub('gateway') gateway.should_receive(:authorize) > > and next you can either stub PaypalGateway.new: > ActiveMerchant::Billing::PaypalGateway.stub(:new).and_return gateway > > or what I'd more likely do: > Payment.stub(:gateway).and_return gateway > Thanks Pat, this worked great and I think helping get my head around doing this. I do have one additional question... I am testing a module here, and noticed that I had to both include the module (Payment) *and* in my spec call Payment#authorize_payment to get things working with the stub. It seems kind of strange as if I did not include the module at the top, then I would get 'undefined method `authorize_payment' for Payment:Module' when called in the spec, which makes sense. But what does not make sense is that when I do include the Module at the top, I still have to call Payment#authorize_payment and not just authorize_payment to get the stub to take (the test passes in both cases, when not explicitly declaring Payment#... the mock does not take). So it seems that it is as if there are two versions of Payment module --- one which is explicitly connected via the rspec stub, and the other which is the native. Once I stub Payment explicitly, I must explicitly declare it on my calls, otherwise it goes to the native code. Is this correct? I thought if I just removed the line 'Payment.stub(:gateway).and_return(gateway)' that I would not have to call Payment#authorize.... and instead use authorize... but again, in this case the mock does not take. Anyway, I have things working (as below), but interested in why this is so. require 'spec_helper' include Payment describe Payment do before(:each) do gateway = stub('gateway') Payment.stub(:gateway).and_return(gateway) gateway.stub!(:authorize).and_return(gateway_authorize_success_response) end it "should authorize payment with paypal using a valid card" do response = Payment.authorize_payment(payment_info_success, 'Bet', 1000) ... end I.E., why does this not hit the stub: it "should authorize payment with paypal using a valid card" do response = authorize_payment(payment_info_success, 'Bet', 1000) ... end > > either one will get you there. > > Pat > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users