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

2

5

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
Terr answered 15/5, 2013 at 21:44 Comment(0)
S
6

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.

Sidsida answered 16/5, 2013 at 3:39 Comment(0)
T
5

Ok, looks like expects is the solution:

it "calls do_something" do
  MyCommand.expects(:do_something)
  MyCommand.execute
end
Terr answered 15/5, 2013 at 21:58 Comment(1)
just had this same question, can confirm that this answer allows me to accurately place an expectation for a class method to be calledEichman

© 2022 - 2024 — McMap. All rights reserved.