Tall Mocha, no toppings please

I finally got around to using a mocking library today at work. I chose Mocha to start, no real reason, just the first name to pop into my head. After about 15 minutes (10 reading docs, and 5 coding) I am in love. Seriously, testing has never been this easy. What would have taken me at least 30 minutes to add new fixtures wihtout breaking old tests or screwing anything else up was easily solved in one to 2 lines per test case.

class SupportControllerTest < ActionController::TestCase
  def test_applicant_activated_view
      Applicant.any_instance.expects(:activated?).returns(:true)

      post :create, :applicant => {:last_name => "Leapfrog", :email => "sos_platform@leapfrogqa.com"}
      assert_select "ul.activated"
  end
end

The first line in the above method mocks out the activated? method on any instance of the Applicant class. Isn’t that simple and clean? Without seeing the rest of the business logic I know it might be hard to accept why I need an entire library to help me with this simple boolean method, but trust me, activated? method is actually delegated to another model which is using an ActiveResource object to truly determine the result.

Dead Simple Mocks For Unit Tests

Yesterday I was testing a Helper (module) I had written for a Rails app I am working on. I wanted to test the helper directly, and not deal with the whole controller and request/response loop just to verify some simple methods. So I started with something like the following:

class TrackingHelperTest < ActiveSupport::TestCase
    include TrackingHelper

    def test_record_event
        ...unimportant...
    end
end

I ran into a problem almost immediately. Some of the methods in this Helper required access to the request object. At first I thought I went down the wrong path, and would need to test this Helper in the context of a controller. Then it hit me, mock the request up. But do I really need a whole class to store and share some instance variables? After pondering this for a few moments I ended up with something like this:

class TrackingHelperTest < ActiveSupport::TestCase
    include TrackingHelper

    # Mocks
    MockRequest = Struct.new(:query_parameters, :path, :headers, :remote_ip, :path_parameters, :query_string)
    attr_accessor :request

    def setup
        @request = MockRequest.new({}, "/some/location", {"HTTP_REFERER" => "somesite.com"}, "1.1.1.1", {:controller => "some", :action => "location"}, "")
    end

    def test_record_event
        ...unimportant...
    end
end

Struct's are simple to use and allow for quick and easy mocking in unit tests. Try it out in your code next time you don't want to build a full class to do something simple.