Here is my proof of concept:
require 'spec_helper'
class MyJob < ActiveJob::Base
def perform
OtherJob.perform_later
OtherJob.perform_later
end
end
class OtherJob < ActiveJob::Base
end
describe MyJob do
subject(:my_job) { MyJob.new }
it 'enqueues job' do
expect { my_job.perform }.to have_enqueued_job(OtherJob).at_least(:once)
expect { my_job.perform }.not_to have_enqueued_job(OtherJob)
end
end
As I understand, have_enqueued_job
checks if job was performed exactly once, so expect { my_job.perform }.to have_enqueued_job(OtherJob)
is same as expect { my_job.perform }.to have_enqueued_job(OtherJob).exactly(:once)
.
But in negative case expect { my_job.perform }.not_to have_enqueued_job(OtherJob)
becomes same as expect { my_job.perform }.not_to have_enqueued_job(OtherJob).exactly(:once)
. So it's quite clear why expect { my_job.perform }.not_to have_enqueued_job(OtherJob)
returns true when there is multiple jobs of same kind, but behavior is confusing.
Tried with rspec-rails 3.6.1.
I'm not sure what you're asking here, it seems your code snippet should fail, as expect { my_job.perform }.not_to have_enqueued_job(OtherJob)
means you haven't enqueued any jobs, and you have. Expectations don't have any knowledge of each other.
Are you saying it passes? Because thats a bug.
I'm saying that expect { my_job.perform }.to have_enqueued_job(OtherJob).at_least(:once)
passes and expect { my_job.perform }.not_to have_enqueued_job(OtherJob)
passes
I faced same issue. You can hack it with:
expect{ my_job.perform }.to have_enqueued_job(OtherJob).exactly(0).times
Most helpful comment
I faced same issue. You can hack it with: