[rspec-users] stuck in testing hell...
apremdas at gmail.com
Tue May 1 11:37:06 UTC 2012
On 1 May 2012 04:24, Patrick J. Collins <patrick at collinatorstudios.com>wrote:
> Hey everyone,
> So here I am, trying to love my testing process-- but I really hit a
> wall today and experienced a moment where testing totally causes a lack
> of productivity... To make a long story short, here's what happened:
> I've been integrating a 3rd party payment service within my app-- The
> way it works is, you get a token for the transaction, and then send a
> request to their API to see if the credit card authorizes, and then if
> it does, you can purchase it and make sure that's valid...
> So I have a purchase model, and I am using state_machine to store the
> transaction state... For example, when an attempt to authorize a
> credit card is done, if that fails, then the state machine transitions
> within a failure block to set the purchase's state to
> ... Ok... So, I made tests to cover all of this behavior, and
> everything was perfect-- all tests were passing, and then I was told:
> "Hey, we want to store the transaction data in the purchase records--
> whether it failed or succeded"... I said: Sure! No Problem!
> The way I had this setup was, an attr_accessor :samurai_transaction
> and then a before_create callback that calls a method
> ... That method basically did:
> Samurai::Processor.authorize( ...bunch o' auth data stuff... )
> So to keep this data around, I made a migration to create the column
> (same name as the attr_accessor property) and then I added serialize
> :samurai_transaction and removed the attr_accessor macro.
> Everything should be exactly the same behaviorally.. Ran my tests to
> verify, and.. FAIL FAIL FAIL FAIL FAIL FAIL FAIL...
> Inspecting the failures, I see that all of a sudden I am getting bogus
> errors about "undefined method `matches_method?' for nil:NilClass"
> I go through everything trying to figure out where this is coming from
> and finally find that it's from my stubbing out the calls to Samurai..
> I was doing:
> auth = stub("auth", :success? => true, :capture => true)
> Samurai::Processor.stubs(:authorize).returns auth
> .. It worked fine before, but apparently something can't handle the
> serialized database column holding a mocked object? No idea...
> So I changed this to:
> auth = OpenStruct.new(:success? => true, :capture => true)
> The error went away, which then made me convinced that it is something
> to do with Mocha..... However, then I saw other tests failing, and
> guess why?
> WRONG NUMBER OF ARGUMENTS FOR CAPTURE (0 for 1).
> .... uhh?
> Samurai has it's own ".capture" method to take funds.. This has some
> conflicts with Rails' internal ".capture"......... For some reason,
> o = OpenStruct.new(:capture => true)
> => wrong number of arguments error...
> So now I have to do:
> o = OpenStruct.new(:kapture => true)
> def o.capture
> and, suddenly I am finding myself in hacky hack land-- and hating every
> minute of it.
> Not to mention my tests still are breaking because of some other
> problems having to do with OpenStruct not being as "simple" of a
> solution as I was hoping.
> ... AAAAAAAAAAAAAAAAAAAAAAGH!
> Patrick J. Collins
The frustration your experiencing is actually a good thing, its your brain
saying "hey something is just not right". Of course our natural reaction to
this is just to get angry, but if we can get past that there is an
opportunity to learn something important. In my limited experience I've
found that listening to tests is one of the best ways to learn. There is
probably something seriously wrong with your existing tests and code. So
instead of trying to work around it, and get your tests to pass, seize the
opportunity and try and work out why your tests and code suck and get to
the bottom of the problem. This is a real opportunity to learn something.
Unfortunately I'm not bright enough to tell you whats wrong, but applying
general principles of good OO and good testing should help. In particular
1. ensuring your tests say what they are testing
2. ensure your unit tests only test responsibilities of their object
3. look for smells (e.g. tests that require lots of mocks are bad tests,
and are indicative of highly coupled code),
Finally an important lesson is that your tests being green is really not
that important. Its much more important that tests
1. say what they do
2. are listened to, so they exert a positive influence on your design
3. make things easy to fix when they go red
> rspec-users mailing list
> rspec-users at rubyforge.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the rspec-users