Plugins - active_mocks

StarAdd to favorites

active_mocks is intended to help in menial mockery with ActiveRecord objects when fiddling with unit and/or functional tests. Mocking AR objects is sometimes a tad tedious. For example, consider a scenario, where you wish to mock an item which has an associated thingy, attributes of which you need to access. You might whip up something similar to the following:

  def test_something_important

    company = flexmock('Company') do |m| # ar object to mock
      m.should_receive(:new_record?).and_return(false)
      m.should_receive(:users).and_return {
        [
         flexmock('User', :name => 'Joe'),
         flexmock('User', :name => 'Bob'),
         flexmock('User', :name => 'Alice')
        ]
      }
    end

    # do stuff with company mock object
  end

yet it is not enough in many cases; when using associations Rails gets inquisitive by checking types and raises an error in case of class mismatch, so you’d need to mock that too.

How to Mock a Mockingbird

Enter active_mocks. To use, just add line ‘include ActiveMock’ after reopening Test::Unit::TestCase in test/test_helper.rb:

  class Test::Unit::TestCase
        include ActiveMock

(no need to say anything about flexmock, it is required in active_mocks.rb)

Usage examples

Roughly from the simpler to just slightly more complex ones:

  require 'mycompiler'
  compiler = activemock(:my_compiler) # or activemock('MyCompiler') works too
  assert compiler.is_a?(MyCompiler)

  # each mock has a default name but it can be overridden
  assert_equal 'some jedi', activemock(:jedi).name
  assert_equal 'Luke Skywalker', activemock(:jedi, :name => 'Luke Skywalker')

  # first level associations are quite easy

  company =  activemock(:company, :has_many_people)
  assert_equal [], company.names

  company = activemock(:company,
          :has_many_people_with_names => ['joe', 'jack', 'jill'])
  assert_equal 'joe', company.people.first.name
  assert_equal 2, company.people.select {|p| p.name.length == 4}.length

  # belongs to works as well
  user = activemock(:user,
                                        :belongs_to_company_with_owner => 'Gill Bates')
  assert_equal 'Gill Bates', user.company.owner

  # and is nil if nothing specified
  user = activemock(:user, :belongs_to_company)
  assert_nil user.company

  # finally (and most convenient perhaps) is that you can specify first level
  # association mocks fill full hash, allowing you to specify many attributes and
  # expected values easily:

  user = activemock(:user,
        :has_many_friends => [
                           {:name => 'Jill', :age => 31},
                           {:name => 'Bob', :age => 27},
                           {:name => 'Alice', :age => 42},
                           {:name => 'Rob', :age => 33}
                         ]
     )
  user_jill = user.friends.find {|u| u.name == 'Jill'}
  assert_equal 31, user_jill.age
  assert_equal 4, user.friends.length

Note that activemock is just a wrapper over flexmock and options you pass to activemock are passed to flexmock as well (with the exception of special association symbols).

Oh, and I’ve alias_method ‘d activemock to just mock in my test suites, so you can save even more in typing.

Bugs

Probably some, haven’t found yet (patches with matching test cases are welcome!)

Licence: MIT (attached)

Edvard Majakari

Edvard Majakari

http://majakari.net/code/plugin-active_mocks

svn://majakari.net/public/rails/plugins/active_mocks/trunk

Rails' (MIT)

  • Currently 0.0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Testing

Tags

Comments

Add a comment

Search Plugins

Query syntax

Plugins by Category

Sponsors

Rails Kits: Get Code. Get Moving.

Have a comment?