I'm trying to use the new have_enqueued_email matcher in one of my specs, but RSpec keeps telling me the format is incorrect
.deliver_nowexpect { post(:email_quote, params: quote_params) }.to have_enqueued_email(MyMailer, :quote)Test to pass
Test fails with the error :
You must pass an argument rather than a block to `expect` to use the provided matcher (have enqueued email QuoteMailer, :quote), or the matcher must implement `supports_block_expectations?`.
The test:
describe "#quote_email" do
subject(:quote_email) { post(:email_quote, params: quote_params) }
let(:email) { "[email protected]" }
let(:quote_params) { { item: item_params, email: email } }
let(:item_params) do
{ variant_id: variant.id, quantity: 100, decoration_id: decoration.id, number_of_colors: 1, is_sample: false }
end
before { ActiveJob::Base.queue_adapter = :test }
it "properly schedules the Mailer for sending the email" do
expect { subject }.to have_enqueued_email(QuoteMailer, :quote)
end
end
The code for invoking in the controller:
def email_quote
item = params.require(:item).permit!.to_h
email = params.require(:email)
QuoteMailer.quote(item, email).deliver_later
render json: true
end
That's strange.
Can you drop a breakpoint before this line:
expect { subject }.to have_enqueued_email(QuoteMailer, :quote)
and check the source of have_enqueued_email? In case you use Pry:
> $ have_enqueued_mail
it should be:
def have_enqueued_mail(mailer_class = nil, mail_method_name = nil)
HaveEnqueuedMail.new(mailer_class, mail_method_name)
end
:have_enqueued_email is an alias of have_enqueued_mail.
Can you call have_enqueued_email(QuoteMailer, :quote).supports_block_expectations?, is this method defined, does it evaluate to true?
I'm not familiar with Pry, so I tried the command you told to use:
> have_enqueued_mail
=> #<RSpec::Matchers::BuiltIn::Has:0x00007f8e87a4e558 @args=[], @block=nil, @method_name=:have_enqueued_mail>
0> have_enqueued_email(QuoteMailer, :quote).supports_block_expectations?
=> false
> have_enqueued_mail => #<RSpec::Matchers::BuiltIn::Has:0x00007f8e87a4e558 @args=[], @block=nil, @method_name=:have_enqueued_mail>This is your problem you're not using the right matcher, thats the
has_<n>matcher which is not the same. Are you using rspec-rails from Github or from4.0.0.beta3or4.0.0.beta4?
normal gem installation
group :test do
gem "factory_bot_rails", require: false
gem "rails-controller-testing"
gem "rspec-collection_matchers"
gem "rspec-nc"
gem "rspec-rails"
gem "rspec_junit_formatter"
gem "simplecov", require: false
gem "timecop"
end
Ok, you need to use 4.0.0.beta3 or 4.0.0.beta4 to use this matcher. Rubygems will not give you beta's unless you ask for them, change gem "rspec-rails" for gem "rspec-rails", "4.0.0.beta4"
Also, I suggest moving rspec-rails to :development, :test group as doc suggests.
Some background https://github.com/rspec/rspec-rails/issues/2200#issuecomment-549389317 https://github.com/rspec/rspec-rails/pull/2117
~I'm not sure thats relevant @pirj, the matcher didn't exist before 4.0.0 you'd need a beta anyway.~
Edit, I was wrong.
Thanks for the clarifications. I think I just got lost in all the docs I was reading about this matcher, that I missed the point this isn't released yet officially.
this is what threw me off : https://www.rubydoc.info/gems/rspec-rails/RSpec%2FRails%2FMatchers:have_enqueued_mail
As the version on top says 3.9.0
It is officially released, we just haven't published as 4.0.0 final yet.
My apologies, it seems it was shipped in 3.9.0 I mis-remembered and then mis-read the change log :joy: , yes there is a bug with the require, you can work around it by requiring it manually.
I've release 3.9.1 as a fix for this, it seems silly not to.
Most helpful comment
I've release 3.9.1 as a fix for this, it seems silly not to.