Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Negative have_enqueued_job does not work as expected with multiple jobs of same kind #1870

Closed
povilasjurcys opened this issue Sep 13, 2017 · 4 comments · Fixed by #2069
Closed

Comments

@povilasjurcys
Copy link

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.

@JonRowe
Copy link
Member

JonRowe commented Sep 13, 2017

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.

@povilasjurcys
Copy link
Author

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

@awcodify
Copy link

awcodify commented Mar 23, 2018

I faced same issue. You can hack it with:

expect{ my_job.perform }.to have_enqueued_job(OtherJob).exactly(0).times

@marciojg
Copy link

marciojg commented Mar 23, 2021

Try this. Worked for me

expect{ my_job.perform }.to have_enqueued_job(OtherJob).at_least(0).times

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants