Testing PayPal Express with ActiveMerchant’s BogusGateway (and how to make it work)
If you’re writing a Rails app with PayPal Express checkout, and having trouble testing because ActiveMerchant’s BogusGateway doesn’t support PayPal-specific methods like
setup_purchase, here’s a fix. I spent a while figuring this out the other day so I thought I’d note it here in case someone else is googling.
Presumably you are writing a Rails app, and are following the instructions in the RailsCast #146 Paypal Express Checkout, or something along those lines.
config/environments/test.rb you have:
config.after_initialize do ActiveMerchant::Billing::Base.mode = :test ::STANDARD_GATEWAY = ActiveMerchant::Billing::BogusGateway.new ::EXPRESS_GATEWAY = ActiveMerchant::Billing::BogusGateway.new end
The BogusGateway just mocks the behaviour of a real payment gateway, so that you can run your tests without connecting to a real one — even in test mode. This means you can run your tests offline, for example.
So far so good. Then in your controller you have something like:
response = EXPRESS_GATEWAY.setup_purchase(order.total, :ip => request.remote_ip, :return_url => new_order_url, :cancel_return_url => products_url )
When you try to test the checkout method in your controller, however, you see an error message like:
undefined method `setup_purchase' for #<:billing::bogusgateway:0x000001296aca50/>
The problem is that ActiveMerchant::Billing::PayPalExpressGateway provides a number of methods that BogusGateway doesn’t duplicate. Why not? Well, apparently PayPal Express is a bit of an odd duck in the ActiveMerchant world, and mumble mumble no real reason.
There’s a pull request by sideshowcoder submitted to ActiveMerchant which creates a PayPalBogusGateway that does all the necessary PayPal-Express-specific things, but it got turned down as “not a common enough use case”. Personally I think that ActiveMerchant shouldn’t have shipped the Paypal Express functionality in an untestable form, but whatevs. You can use sideshowcoder’s fix in your own app, as follows.
First of all, in order to monkeypatch in this way, you’re going to have to take a copy of the gem and put it in your
vendor/ directory. I did so following the instructions in this blog post, specifically:
- Download the activemerchant gem from rubygems.org
gem unpack ~/activemerchant-1.33.0.gem --target vendor/gems
- Repeat for the active_utils gem, which is also required.
Then in my Gemfile, I have:
gem 'activemerchant', '1.33.0', :path => 'vendor/gems/activemerchant-1.33.0', :require => 'active_merchant' gem 'active_utils', '1.0.5', :path => 'vendor/gems/active_utils-1.0.5'
Finally, after running “bundle install” to make sure that all worked, I dropped paypal_bogus.rb into the appropriate place in my
Congratulations, you can now test your Rails app’s interaction with PayPal Express. Hopefully the googles will take note, and the next person searching for this won’t have to pound their head against it quite as hard as I did.
(Thanks also to Ben Bleything for some help on Twitter with the vendored gem part of this.)