11

rspec-rails (2.7.0) rails (3.0.10) post: Rails 3.1 Error Catching is irrelevant for me.

Code:

class ApplicationController < ActionController::Base
  unless Rails.application.config.consider_all_requests_local
    rescue_from ActiveRecord::RecordNotFound, :with => :render_404
    rescue_from Exception, :with => :render_500
    rescue_from FunnyException, :with => :my_errors

    def my_errors(exception)
      #some stuff for production
      puts "=======From top====#{Rails.application.config.consider_all_requests_local}"
    end
  else
    rescue_from FunnyException, :with => :my_errors
    def my_errors(exception)
      #some stuff for development
      puts "=====From bottom======#{Rails.application.config.consider_all_requests_local}"
    end
  end
end

This code perfectly works with production/development... problem is when I wanna test it with rspec. How to switch test case between environments?

I tried adding something like:

before do
  Rails.application.config.consider_all_requests_local = true
end

I get:

...=====From bottom======true .=====From bottom======true .=====From bottom======true .=====From bottom======true

so tried

before do
  Rails.application.config.consider_all_requests_local = false
end

so I get:

...=====From bottom======false .=====From bottom======false .=====From bottom======false .=====From bottom======false

How is that even possible? ... same with changing spec_helper

config.before(:each) do
  Rails.application.config.consider_all_requests_local = false
end

unless is not working. Top section is unreachable with rspec... always hits Bottom why ? I assume it is somehow tied now with Rack... but is there any solution to dynamically change this behavior inside rspec?

regards

Community
  • 1
  • 1
Piotr Mąsior
  • 1,580
  • 1
  • 11
  • 20

4 Answers4

22

Ok I found quite easy solution

before do
  Rails.application.config.consider_all_requests_local = false
  load "application_controller.rb"
end

after do
  Rails.application.config.consider_all_requests_local = true
  load "application_controller.rb"
end

It is part of anonymous application controller test suite.

You have to add after block... because this change will persist through other suites.

Any improvements welcome :D

edit: Using spork and guard causes for me sometimes random errors... before :all seems to solve that problem

Piotr Mąsior
  • 1,580
  • 1
  • 11
  • 20
  • 5
    I'm not sure if my situation is the same, but I had to add: `Rails.application.config.action_dispatch.show_exceptions = true` to the before block. and `... = false` to the after. – d_rail Jun 20 '13 at 03:38
  • Amazing solution, exactly what I was looking for. Thank you! – William Weckl Aug 22 '15 at 14:20
  • 3
    It is failing for me when I am running the full suite using `rake spec`. It passes only when I run the specific the `feature` spec.. – Arup Rakshit Dec 26 '15 at 10:15
  • 2
    Why `load "application_controller.rb"` is used here? – Spyros May 05 '16 at 09:02
2

You also need to set Rails.application.config.action_dispatch.show_exceptions = true. But since Rails caches that value, this will only work if you run your spec on its own. Fortunately, you can change these options only for the current spec by mocking the config:

  before do
    method = Rails.application.method(:env_config)
    expect(Rails.application).to receive(:env_config).with(no_args) do
      method.call.merge(
        "action_dispatch.show_exceptions" => true,
        "action_dispatch.show_detailed_exceptions" => false,
        "consider_all_requests_local" => false
      )
    end
  end

Thanks to:

maikel
  • 1,669
  • 18
  • 15
1

I found that with cucumber-rails the right way of doing it is to add the @allow-rescue tag.

TerryYin
  • 174
  • 2
  • 6
0

The logic block is defined on class level, which gets evaluated during the class load time. This is why it will not go to 'else' even if you manually set it to false at run time.

I am also curious to know what's the best way to test this. My only clue is somehow reload or re eval ActionController, similar to reload! method in rails console.

ez.
  • 7,604
  • 5
  • 30
  • 29