Problem Testing ActiveResource with Mocks in Rails

A note for those who are using ActiveResource.

I ran into a bit of a problem the other day, not with using the HttpMock class itself. Mocks work pretty well in ActiveResouce. The problem came about when I tried to not use HttpMock. I almost tore my hair out but eventually a simple solution came. Thanks to Jason for the shoulder surfing effect.

First – The Problem
In my functional tests I have two controller tests. Test A is tested against the an actual resource. Test B uses ActiveResource’s HttpMock class to fake resources.

The problem is with Test A. If I run the test on its own, ie ruby /test/functional/a_test.rb the test will run fine. If I run it as part of rake test or rake test:functionals I get errors from test A complaining that no response is set up for any of the requests made in the test. (ActiveResource::InvalidRequestError: No response recorded for...)

So it would seem that it is trying to use HttpMock even though I have not required it in this test. Somehow it is staying in scope having been required in test b. I know that HttpMock overrides the http class in ActiveResource::Connection so perhaps that class is not being reloaded and the method is staying overridden. I couldn’t find a way of resetting the environment that worked.

The Fix that I wish I found 6 hours earlier…

In Test B the following line was present outside any class definitions to make ActiveResource mocks work:
require 'active_resource/http_mock'

Moving that line into the TestCase class seems to restrain the scope of HttpMock so that it doesn’t interfere with other tests.
I placed the line inside the test setup method and all was well eg:

class BControllerTest < Test::Unit::TestCase
  def setup
    require 'active_resource/http_mock'
    ##rest of your code below....
  end
  #
  #
  #
end

My tests ran happily ever after.

6 thoughts on “Problem Testing ActiveResource with Mocks in Rails

  1. Thanks for posting about this John. I’m sure I would have hit the same problem sooner or later.

  2. Another thanks!!! here :) , only after reading your reasoning it occured me that I have require-ed ‘active_resource/http_mock’ in test helper, effectively destroying connection for my non-mock controller test. (Known case of “being too smart”. Or maybe too “DRY” :)

    Thanks!

    Karel

  3. Is this solution not dependent on how the tests are loaded up ?

    Putting the require in the setup block does not really solve the issue, unless you are rolling back HttpMock internals in the teardown. If another test which does not work well with HttpMock loaded runs after BControllerTest things should fail once again.

  4. Yes sir, Thank you!

    I only wasted three hours instead of your six. Still you saved me. Thanks!

  5. Uh, I think I spoke to soon.

    FWIW, your solution ended up not working for me. I instead had to spend some time modifying my test_helper by adding two methods to turn off and on the mock behavior in setup calls.

    Here is a link to the code snipit i ended up adding:

    http://pastie.org/405434

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>