If you use test doubles in your Ruby unit tests as I do, there are several tools available. If you use RSpec, the obvious choice is rspec-mocks.

It is possible to use rspec-mocks with Minitest as well. Here’s how.

The Relish documentation for rspec-mocks shows how to integrate with Minitest. Those instructions work and that’s where you should start. If you create a MinitestRSpecMocksIntegration module as outlined in the documentation, you should be (almost) good to go.

Integrating RSpecMocks with Minitest
require 'minitest/autorun'
require 'rspec/mocks'
module MinitestRSpecMocksIntegration
include ::RSpec::Mocks::ExampleMethods
def before_setup
::RSpec::Mocks.setup
super
end
def after_teardown
super
::RSpec::Mocks.verify
ensure
::RSpec::Mocks.teardown
end
end
Minitest::Test.send(:include, MinitestRSpecMocksIntegration)

If you don’t want this module included in all of your test cases, you can leave out the last line and instead include the module in only the test case subclasses where it’s needed.

Even with this setup in place, I ran into one issue trying to use the spy API of rspec-mocks, specifically the have_received matcher. The rspec-mocks version of the expect method is not as full-featured as the version in rspec-expectations and doesn’t work with the have_received matcher.

There will be a fix for this issue in rspec-mocks 3.4, but that version has not yet been released at the time of this writing.

For rspec-mocks 3.3.x and earlier, there is a workaround. You need to use rspec-expectations along with rspec-mocks. If you change your MinitestRSpecMocksIntegration module as follows, the have_received matcher will work properly.

Workaround for rspec-mocks 3.3.x and earlier
require 'minitest/autorun'
require 'rspec/mocks'
require 'rspec/expectations'
module MinitestRSpecMocksIntegration
include ::RSpec::Mocks::ExampleMethods
include ::RSpec::Matchers
# ... rest as before ...
end

Note that I don’t use Minitest’s spec syntax. There may be other issues to address if you do.

Thanks to Myron Marston for responding to this issue so quickly, and for committing an excellent fix for it.

Other Options

If you’d rather use a different mocking framework with Minitest, there are a few other options:

  • Minitest comes with its own test double framework. It has the basic functionality, but I could never quite get used to it.

  • FlexMock was originally developed by Jim Weirich (RIP). I’ve used it in the past and was pretty happy with it, but it stopped working with newer versions of Ruby. Since then, Sylvain Joyeux has stepped up as the new maintainer of FlexMock and fixed the issues I ran into. Thanks for taking this on, Sylvain!

  • Mocha seems like a pretty complete test double library, and a lot of people use it. I don’t have any first-hand experience with it, but it is definitely a viable option.