Skip to main content

Mocking with an alternative framework

In addition to rspec, mocha, flexmock, and RR, you can choose an alternate framework as the mocking framework. You (or the framework authors) just needs to provide an adapter that hooks RSpec's events into those of the framework.

A mock framework adapter must expose three methods:

  • setup_mocks_for_rspec
    • called before each example is run
  • verify_mocks_for_rspec
    • called after each example is run
    • this is where message expectation failures should result in an error with the appropriate failure message
  • teardown_mocks_for_rspec
    • called after verify_mocks_for_rspec
    • use this to clean up resources, restore objects to earlier state, etc
    • guaranteed to run even if there are failures

Mock with alternate framework

Given a file named "expector.rb" with:

class Expector
class << self
def expectors
@expectors ||= []
end

def clear_expectors
expectors.clear
end

def verify_expectors
expectors.each {|d| d.verify}
end
end

def initialize
self.class.expectors << self
end

def expectations
@expectations ||= []
end

def expect(message)
expectations << message.to_s
end

def verify
unless expectations.empty?
raise expectations.map {|e|
"expected #{e}, but it was never received"
}.join("\n")
end
end

private

def method_missing(name, *args, &block)
expectations.delete(name.to_s)
end

public

module RSpecAdapter
def setup_mocks_for_rspec
# no setup necessary
end

def verify_mocks_for_rspec
Expector.verify_expectors
end

def teardown_mocks_for_rspec
Expector.clear_expectors
end
end
end

Given a file named "example_spec.rb" with:

require File.expand_path("../expector", __FILE__)

RSpec.configure do |config|
config.mock_with Expector::RSpecAdapter
end

RSpec.describe Expector do
it "passes when message is received" do
expector = Expector.new
expector.expect(:foo)
expector.foo
end

it "fails when message is received" do
expector = Expector.new
expector.expect(:foo)
end
end

When I run rspec example_spec.rb --format doc

Then the exit status should be 1

And the output should contain "2 examples, 1 failure"

And the output should contain "fails when message is received (FAILED - 1)".