Search code examples
ruby-on-railsrspecrspec-rails

Rspec test mailer from controller with params in helper


I’m having a rather odd rspec failure that feels like a test configuration issue or a bug in rspec or rspec-rails (rspec 3.4.0 and rspec-rails 3.4.2). I’m hoping for any advice about the matter:

I have a controller test which simply invokes a mailer method whose template utilizes that helper and I get an error from the helper function where I use the params.

describe MyController, :type => :controller do
  describe "POST send_a_specific_type_of_email" do
    it "sends the fact sheet" do
      ActionMailer::Base.deliveries = []
     post :send_a_specific_type_of_email, params
     expect(ActionMailer::Base.deliveries.count).to eq(1)
    end
  end
end

This results in an error which relates to a helper method I have which utilizes params.

Failure/Error: if params[:some_value] == "on"

ActionView::Template::Error:
 undefined method `params' for #<MyMailer:0x007fdcf56020f0>
# ./app/helpers/mycontroller_helper.rb:139:in `display_mycontroller_price'
# ./app/views/mycontroller/_items.html.erb:26:in `_app_views_mycontroller__items_html_erb__2241527061928464634_70293475039080'
# ./app/views/production_mailer/email_mycontroller.html.erb:17:in `_app_views_production_mailer_email_mycontroller_html_erb___301577404429349505_70293454886780'
# ./app/models/production_mailer.rb:51:in `email_mycontroller'
# ./app/controllers/mycontroller_controller.rb:40:in `send_a_specific_type_of_email'
# ./lib/authenticated_system.rb:75:in `catch_unauthorized'
# ./spec/controllers/mycontroller_controller_spec.rb:109:in `block (4 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# NoMethodError:
#   undefined method `params' for #<MyMailer:0x007fdcf56020f0>
#   ./app/helpers/mycontroller_helper.rb:139:in `display_mycontroller_price'

I’ve tried setting an expectation for the helper and mailer to return nil if that mailer method or helper method is called but they never resolve that error. I’m both confused and surprised that stubbing the mailer OR helper methods did nothing.

Here's how I've tried stubbing:

# does nothing
expect(MyHelper).to receive(:display_mycontroller_price).and_return(nil)

# does cover up the issue but causes the above test to fail because 
# deliver_now quantities are no longer being checked, thus negating the purpose of the test in the first place
expect(FactSheetHelper).to receive(:display_factsheet_price).with(project.data).and_return(0)
expect(ProductionMailer).to receive(:params).and_return(params)
expect(message_delivery).to receive(:deliver_now)

How can I stub that Helper method from a controller spec test succesfully, or is this a bug in rspec somewhere?


Solution

  • The error says it all, you can't use params inside a Mailer (or within the context of a Mailer through a Helper). Refactor, so you pass the value as an argument to the mailer method instead.