public

Mocha/MiniTest integration options

  • Download Gist
mocha-minitest-integration-options.md
Markdown

Mocha/MiniTest integration

I think that the approach @tenderlove has suggested to avoid monkey-patching MiniTest (and the way MiniTest works) means that to use Mocha with MiniTest, you would either need to include the Mocha integration module into every test case, or define your own test case class inheriting from MiniTest::Unit::TestCase.

This works well for Rails (i.e. ActiveSupport), because it already defines a new test case class (ActiveSupport::TestCase) which is a suitable place to include the Mocha integration module.

If we were to go down this route, in non-Rails Ruby projects you'd need to do one of the following...

Option A

    class MyTestCase < MiniTest::Unit::TestCase
      include Mocha::Integration::MiniTest
    end

    class TestCaseOne < MyTestCase
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

    class TestCaseTwo < MyTestCase
      def test_bar
        o = mock
        mock.expects(:bar)
      end
    end

Option B

    class TestCaseOne < MiniTest::Unit::TestCase
      include Mocha::Integration::MiniTest
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

    class TestCaseTwo < MiniTest::Unit::TestCase
      include Mocha::Integration::MiniTest
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

The explicit-ness and the lack of monkey-patching is clearly beneficial, but do you think the above options are too onerous compared to the current behaviour where MiniTest::Unit::TestCase itself is monkey-patched and you could simply do the following :-

    require "minitest/unit"
    require "mocha"

    class TestCaseOne < MiniTest::Unit::TestCase
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

    class TestCaseTwo < MiniTest::Unit::TestCase
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

Or how about this rather crazy option C :-

    class TestCaseOne < Mocha(MiniTest::Unit::TestCase)
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

    class TestCaseTwo < Mocha(MiniTest::Unit::TestCase)
      def test_foo
        o = mock
        o.expects(:foo)
      end
    end

How does the use of Mocha with rspec and bacon compare to the options above?

Using Mocha with Rspec works like this :-

# Gemfile
source :rubygems

gem "rspec-core"
gem "rspec-expectations"
gem "mocha"

# spec.rb
require "bundler/setup"
require "rspec/core"

RSpec.configure do |config|
  config.mock_framework = :mocha
end

describe "mocking" do
  it "foo" do
    o = mock
    o.expects(:foo)
  end
end

The configuration setting causes Rspec to require "mocha/standalone" and "mocha/object" which is the equivalent of require "mocha/api" and "mocha/object" which is in turn the equivalent of require "mocha_standalone".

And with Bacon it works like this :-

# Gemfile
source :rubygems

gem "bacon"
gem "mocha-on-bacon"
gem "mocha"

# spec.rb
require "bundler/setup"
require "bacon"
require "mocha-on-bacon"

describe "mock" do
  it "foo" do
    o = mock
    o.expects(:foo)
  end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.