Mock/Stub out ActiveMerchant?

I'm trying to write some unit tests for a class of mine that uses ActiveMerchant (AM) to talk to Authorize.net (A.net). For the tests though, I don't want AM to actually talk to A.net. Partly because it slows the tests way, way down, partly because it creates a ton of bogus data that clutters up our test account at A.net, and partly because the purpose of the test is to just test *my* class, not AM.

This seemed to me like the perfect time to learn about and use Mock/Stub objects for testing. However, I'm having serious issues getting anything to work. When I stub out any of my other classes, things work exactly like all the documentation I've read indicates, so I know I'm doing something right. However, all the documentation talks about stubbing out classes, but for AM, I think what I need to stub out is ActiveMerchant::Billing::Base, which is a module, not a class. My test just seems to ignore everything I do and uses the real ActiveMerchant::Billing::Base in vendor/plugins, not my stubs.

I cannot possibly be the first person to try to stub out parts of AM so that unit tests aren't constantly trying to talk to the gateway. Anybody got a hint for me? Thanks!

You might want to check out the ‘bogus’ gateway built into AM. I’ve not used it for a while, but I’m pretty sure you can just call it in the way you would Authorize.net:

gateway = ActiveMerchant::Billing::BogusGateway.new

etc.

James.

James Stewart wrote:

You might want to check out the 'bogus' gateway built into AM. I've
not used it for a while, but I'm pretty sure you can just call it in
the way you would Authorize.net:

gateway = ActiveMerchant::Billing::BogusGateway.new

etc.

James.

Thanks for the info. I hadn't seen the bogus gateway. That might be what I need to do but I don't think it's an ideal solution at all. For that to work, I think I would either need to put code in my class that's specifically for testing (not very pragmatic, IMHO), or stub out a portion of the very class I'm trying to test, leaving the lines of real code that create the gateway object completely untested, also not very pragmatic.

Plus, the BogusGateway appears very limited (only accepts 2 credit card #'s: 1 and 2) and doesn't seem to provide all the functionality that I was hoping to give my stubs for complete testing of my class.

Ideally, my class should be interacting with what it 'thinks' is ActiveMerchant exactly as if it really were talking to AM, and not realize it's only talking to my stub that's pretending to be AM, providing all the features that my class expects of AM. </run-on sentence>

I don’t know anything specifically about ActiveMerchant, but have you tried using Mocha (http://mocha.rubyforge.org)?

Yah, I looked at that. Doesn't appear to provide what I need. Thanks though.

James Mead wrote:

Just giving this one a bump to see if a new day brings any new ideas. Thanks.