Within a feature spec, how to test that a Devise m

2019-08-14 19:01发布

问题:

I have a feature test for user registration. How do I test that Devise confirmation instructions are sent correctly? I don't need to test the content of the email, only that the mailer has been called.

I am sending mails in the background.

#user.rb    
def send_devise_notification(notification, *args)
  devise_mailer.send(notification, self, *args).deliver_later
end

I have tried a few approaches that work for other mailers, including

it "sends the confirmation email" do
  expect(Devise.mailer.deliveries.count).to eq 1
end

and

it "sends the confirmation email" do
  message_delivery = instance_double(ActionMailer::MessageDelivery)
  expect(Devise::Mailer).to receive(:confirmation_instructions).and_return(message_delivery)
  expect(message_delivery).to receive(:deliver_later)
end

none of which are working as expected for Devise messages.

What am I doing wrong?

Edit

The feature spec looks like this:

feature "User signs up"  do
  before :each do
    visit '/'
    click_link 'Sign up'
    fill_in 'user_email', with: valid_attributes[:email]
    fill_in 'user_password', with: valid_attributes[:password]
    fill_in 'user_password_confirmation', with: valid_attributes[:password]
    click_button 'Sign up'
  end
  it "sends the confirmation email" ...

end

回答1:

Since you're doing a high level feature spec, I would wager that as a result of clicking the 'Sign up' button, what you want to confirm is that an email job has been added to the queue.

In order to do that, you may have to slightly change your spec set up:

feature "User signs up" do
  before :each do
    visit '/'
    click_link 'Sign up'
    fill_in 'user_email', with: valid_attributes[:email]
    fill_in 'user_password', with: valid_attributes[:password]
    fill_in 'user_password_confirmation', with: valid_attributes[:password]
  end

  it "queues up a confirmation email job" do
    expect { click_button 'Sign up' }.to \
      have_enqueued_job(ActionMailer::DeliveryJob)
  end
end

You can have a look at the have_enqueued_job matcher for more options if the above one doesn't quite suit your use case.