Hardmock

April 9th, 2007

Most ruby developers who use mock libraries are familiar with either Mocha or Flex Mock. However not many are familiar with the mock library that I use, Hardmock.

Hardmock takes mocking one step further to assert order between mocks, much like the Java mocking library EasyMock


  class Person
    def initialize(car, wallet)
      @car = car
      @wallet = wallet
    end

    def go_to_movies
      @car.drive_to_movies
      @wallet.pay_for_ticket("10.00")
      @car.drive_home
    end
  end

  ...

  # in tests
  def setup
    create_mocks :car_mock, :wallet_mock
    @person = Person.new(@car_mock, @wallet_mock)
  end

  # This test will pass
  def test_go_to_movies
    @car_mock.expects.drive_to_movies
    @wallet_mock.expects.pay_for_ticket("10.00")
    @car_mock.expects.drive_home

    @person.go_to_movies
  end

  # This test will fail since we 
  # drive home before we paid for the ticket
  def test_go_to_movies_failure
    @car_mock.expects.drive_to_movies
    @car_mock.expects.drive_home
    @wallet_mock.expects.pay_for_ticket("10.00")

    @person.go_to_movies
  end

Another one of my favorite perks of Hardmock is the open assertions of parameters. For the most part, parameters are expected to equal what is given in the initial assertions, however sometimes there’s complications on asserting the parameters given.



  def test_allow_any_money_for_ticket
    @car_mock.expects.drive_to_movies
    @wallet_mock.expects.pay_for_ticket do | amount |
      # this will be executed when "pay_for_ticket" is called on the mock

      # Only allow dollar amounts
      assert_match(/^\d+\.\d{2}$/, amount)

      # of course the last value in this block 
      # with be returned from the mock to the caller
      "the ticket" 
    end
    @car_mock.expects.drive_home

    @person.go_to_movies
  end

Hardmock was written by the solid developers at Atomic Object

Leave a Reply