Reputation: 634
I'm trying to check if a method isn't invoked within an after_update
callback.
I'm currently doing:
class Foo
def self.call; end
end
def Model < ActiveRecord::Base
after_update :do_something
def do_something
return unless title_changed?
Foo.call
end
end
In the test it works like that:
test 'Foo.new.bar is invoked' do
mock = Minitest::mock.new
mock.expect :call, nil
Foo.stub(:call) { update_record_to_fire_callback }
mock.verify
end
And it beautifully pass, but now I'm trying to do the opposite but without luck as I don't know how to do it. If I do assert_not mock.verify
Minitest complains anyway for the method to be executed.
Or maybe there are other way to check a method isn't invoked? The method will do an expensive request, so, I want to avoid that.
I'm using Rails 5 and sadly Minitest. I'm open to add any gem that can work with these versions.
Upvotes: 2
Views: 3138
Reputation: 86
Since you're open to adding a gem, mocha works well for this. Add the gem, then use mocha's Expectation#never. Your test can then look like:
test 'Foo.new.bar is not invoked' do
model = Model.new
Foo.expects(:call).never
model.update!(not_the_title: 'value')
end
Upvotes: 5
Reputation: 8984
The easiest way to accomplish this is to stub the method that you want to ensure isn't called and have it raise an error.
class ModelTest < ActiveSupport::TestCase
test "does not call Foo.call when title is not changed" do
model = Model.new
refute model.title_changed?
Foo.stub(:call, -> { raise "Foo was called!" }) do
model.title = "something new"
end
assert model.title_changed?
end
end
There is no assertion to check that an error was not explicitly raised. Rails does have assert_nothing_raised
, but Minitest does not. You can add it if you like.
class ModelTest < ActiveSupport::TestCase
test "does not call Foo.call when title is not changed" do
model = Model.new
refute model.title_changed?
Foo.stub(:call, -> { raise "Foo was called!" }) do
assert_nothing_raised do
model.title = "something new"
end
end
assert model.title_changed?
end
end
Upvotes: 1