Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a mixed-in class method is being called with RSpec and Mocha?

I have a module:

module MyModule
  def do_something
    # ...
  end
end

used by a class as follows:

class MyCommand
  extend MyModule

  def self.execute
    # ...
    do_something
  end
end

How do I verify that MyCommand.execute calls do_something? I have tried partial mocking with mocha, but it doesn't fail when do_something is not called:

it "calls do_something" do
  MyCommand.stubs(:do_something)
  MyCommand.execute
end
like image 467
Sébastien Le Callonnec Avatar asked May 15 '13 21:05

Sébastien Le Callonnec


1 Answers

Well, it's one solution.

As I mentioned in this SO post, there are two strategies to mocking/stubbing:

1) Using mocha's expects will auto-assert at the end of your test. In your case, it means if MyCommand.execute is not called after expectsing it, the test will fail.

2) The more specific/assertive way to do this is to use a combination of stubs and spies. The stub creates the fake object with the behavior you specify, then the spy check so to see if anyone called the method. To use your example (note this is RSpec):

require 'mocha'
require 'bourne'

it 'calls :do_something when .execute is run' do
  AnotherClass.stubs(:do_something)

  MyCommand.execute

  expect(AnotherClass).to have_received(:do_something)
end

# my_command.rb
class MyCommand
  def self.execute
    AnotherClass.do_something
  end
end

So the expect line uses bourne's matcher to check and see if :do_something was called on `MyCommand.

like image 195
adarsh Avatar answered Sep 29 '22 06:09

adarsh