21

I'm using MiniTest 2.12.1 (the latest version of the stock testing framework shipped with Ruby >= 1.9) and I can't figure out how to mock a class method with it, the same way it's possible with the likes of Mocha, for example:

product = Product.new
Product.expects(:find).with(1).returns(product)
assert_equal product, Product.find(1)

I've been dabbling the Internet for days and I'm still to find a reasonable answer to this. Please help?

  • I think is not possible to make this kind of _mocking_ with `minitest/mock`, [duplicated?](http://stackoverflow.com/questions/7211086/how-do-i-stub-things-in-minitest) – fguillen May 11 '12 at 14:44

2 Answers2

19

This might not be helpful to you if you're stuck using 2.12.1, but looks like they added method stubbing to minitest/mock in HEAD here.

So, were you to update to minitest HEAD, I think you could do this:

product = Product.new
Product.stub(:find, product) do
  assert_equal product, Product.find(1)
end
Adam
  • 3,148
  • 19
  • 20
  • Looks like they've tagged a new version since I wrote this, so no updating to HEAD needed. The most recent version is at 3.5.0 now. If you're using bundler, you can update minitest by making sure you have a line like this in your Gemfile: `gem 'minitest', '3.5.0'`. If you wanted to work off the HEAD version, you would have this in your Gemfile instead: `gem 'minitest', :git => 'git://github.com/seattlerb/minitest.git'`. If you're not using Bundler, I think `gem update minitest` should do it. – Adam Sep 25 '12 at 03:56
  • Just to clarify: this is not exactly equivalent to the mocha solution in the question: The parameters of the `.find` call are not verified with this solution... – severin Jul 29 '13 at 14:53
3

What I do is that I simply stub the class method and replace it with my own lambda function which proves that original function was called. You can also test what arguments were used.

Example:

  test "unsubscribe user" do
    user = create(:user, password: "Secret1", email: "john@doe.com", confirmation_token: "token", newsletter_check: false)

    newsletter = create(:newsletter, name: "Learnlife News")
    unsubscribe_function = -> (email:) { @unsubscribed_email = email }

    Hubspot::Subscription.stub :unsubscribe_all, unsubscribe_function do
      get user_confirmation_en_path(confirmation_token: "token")
    end

    assert_equal @unsubscribed_email, "john@doe.com"
  end
Robin Bortlík
  • 740
  • 7
  • 15