Mocking Ruby Classes?

Posted by Jeremy Voorhis Mon, 10 Jul 2006 08:34:00 GMT

Maybe I missed something, but today I was looking for a generic mocking framework for Ruby that would allow me to create a mock class, not just a mock instance. I almost achieved this with Jim Weirich’s excellent FlexMock, and decided not to try out Test::Unit::Mock or SchMock just yet. Instead, I ended up writing the code at the end of this post. If you have a favorite mocking tool that I haven’t mentioned, or know how to mock classes with an existing tool, please post a comment!

Here is the code for SimpleMock:

module SimpleMock
  module Recorder
    def messages_received
      @messages_received ||= []
    end

    def method_missing message, *args, &block
      messages_received << { :message => message.to_s, :arguments => args }
    end

    def message_received? message, *args
      message = message.to_s
      !messages_received.select { |m| m[:message]  message && m[:arguments]  args }.empty?
    end
  end

  class Base
    include Recorder
    extend Recorder
  end

  module Assertions
    def assert_message_received mock, message, args
      error_message = ”#{mock}.#{message}(#{args.join(’,’)}) expected but not received.\n” +
          ”#{mock} received the following messages: \n #{mock.messages_received.inspect}” 

      assert mock.message_received?(message, args), error_message
    end
  end
end
Here is how it is used:

class Entry < SimpleMock::Base; end

class EntriesController < ActionController::Base
  include RapidResource::Crud
  # Re-raise errors caught by the controller.
  def rescue_action(e) raise e end
end

class RapidResourceTest < Test::Unit::TestCase
  include SimpleMock::Assertions

  def setup
    @controller = EntriesController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
  end

  def test_find_member_should_find_entry_by_id
    get :show, :id => 7
    assert_message_received Entry, :find, 7
  end
end

Comments

  1. Steve Purcell said 11 days later:

    There’s also MockR, of which I’m the author. It’s similar to FlexMock and Schmock, but has what I believe is a particularly natural syntax.

(leave url/email »)