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!

On Apr 11, 2007, at 2:45 PM, Jon G. wrote:

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.

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 S.

Work: http://jystewart.net/process/
Play: http://james.anthropiccollective.org

James S. wrote:

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>

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

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

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


James.