Awesome Open Source
Awesome Open Source

StrictlyFake Build Status Gem Version

Sometimes fakes are a good choice. But the price is high. In particular, they make changing code harder. You rename a method, but all tests that stub the previous version keep passing. It would be nice if those started to fail so that when they're green again, you can be certain that everything that had to be updated was updated. Well, now you can.

To be fair, you already can in Rspec with their verifying double. But what about Minitest? And there are still differences. Unlike verifying double:

  • here you need to supply real objects to create fakes. That's controversial - as it goes against the idea of testing in isolation - but realistically, at least in Rails, everything is loaded anyway, so that's a moot point;
  • strictly_fake is aware of autogenerated methods (e.g. ActiveRecord model accessors);
  • strictly_fake does not stub constants (e.g. classes). You can, however, pass a fake to Minitest's Object#stub to achieve this (see example below);
  • strictly_fake performs a full parameter check, comparing required, optional and keyword arguments (veryfing double only checks arity afaik).


Add this line to your application's Gemfile:

gem 'strictly_fake'

And then execute:

$ bundle install


require 'strictly_fake'

# Given we don't want to actually pay in tests
class PaymentGateway
  def pay(recipient, amount, reference = nil);
    # calls remote payment provider...

# We can use a fake instead
payment_gateway =

# Let's stub a method that _isn't_ defined in PaymentGateway:
# => throws "Can't stub non-existent method PaymentGateway#bar (StrictlyFake::Error)"

# Let's stub an existing method, but with a wrong signature: 
payment_gateway.stub(:pay) { |amount| }
# => throws "Expected PaymentGateway#pay stub to accept (req, req, opt=), but was (req) (StrictlyFake::Error)"

# All good now!
payment_gateway.stub(:pay) { |recipient, amount, reference = nil| 'Success!' }'Dave', 10)
# => 'Success!'

# Makeshift mock
invoked = false
payment_gateway.stub(:pay) do |recipient, amount, reference = nil|
  # Further arguments check
  invoked = true
# => Pass

# Stubbing class methods is no different
time =

time.stub(:now) { 'XYZ' }
# => 'XYZ'

# Combine with Minitest stub to actually stub constant
Time.stub :now, do
  # => 'XYZ'

Note: Minitest is required for assert* to work.


After checking out the repo, run bundle install to install dependencies. Then, run bundle exec rspec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to


Bug reports and pull requests are welcome on GitHub at


The gem is available as open source under the terms of the MIT License.

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Ruby (311,839
Fake (289
Stub (259
Related Projects