Reputation: 644
I have the following class:
class Foo
def initialize(foobar:)
@foobar = foobar
end
def call
return if foobar.blank?
do_something_here
end
end
Which is being invoked in an after_commit callback from a model:
included { after_commit :invoke_method_in_poro, on: %I[create update] }
private
def invoke_method_in_poro
Foo.new(foobar: to_json).call
end
Now when I try to test if call
is being invoked, I need to first stub the new method, because I'm getting this error:
NameError: undefined method `call' for class `Foo'
Did you mean? caller
With this code:
foo = Foo
new_mock = Minitest::Mock.new
new_mock.expect :call, nil
foo.stub(:call, new_mock) do
create(:model)
end
mock.verify
My question is, how finally can I test that call
is being invoked?
Upvotes: 1
Views: 378
Reputation: 62688
You're running into a peculiarity of Minitest here: when call
is defined on a method, it appears that something in the minitest stack attempts to call it when an object is defined.
Given this test setup:
require 'minitest/autorun'
class Foo
def call
end
end
class Bar
def test
Foo.new.call
end
end
describe "Bar" do
it "invokes foo.call" do
mock = Minitest::Mock.new(Foo)
mock.expect(:call, nil)
Foo.stub :new, mock do |args|
Bar.new.test
mock.verify
end
end
end
It fails as described. But if you rename call
to my_call
, it passes:
require 'minitest/autorun'
class Foo
def my_call
end
end
class Bar
def test
Foo.new.my_call
end
end
describe "Bar" do
it "invokes foo.my_call" do
mock = Minitest::Mock.new(Foo)
mock.expect(:my_call, nil)
Foo.stub :new, mock do |args|
Bar.new.test
mock.verify
end
end
end
The same test passes under RSpec:
class Foo
def call
end
end
class Bar
def test
Foo.new.call
end
end
describe "Bar" do
it "invokes foo.call" do
mock = double
expect(mock).to receive(:call)
expect(Foo).to receive(:new).and_return(mock)
Bar.new.test
end
end
Upvotes: 1