2

Does Ruby on Rails 3 (3.0.7) offer a mechanism to reload the class cache on demand? I am running some tests where I overwrite some methods in ApplicationController and in some of my models to stub out authentication. For example, I call a method (I'm using Cucumber for testing) in some of my tags (Before('@tag')) that does this:

ApplicationController.send(:define_method, :current_user) do
  @current_user ||= User.where(:id => cookies[:user_id]).first
end

...where the actual current_user method in ApplicationController has a different behavior.

This works great until I need to run some tests in which I do not want to stub out those methods. With config.cache_classes = true set in my test environment, ApplicationController is not reinitialized without my monkey patch, making the tests I don't want to stub out fail. With config.cache_classes = false, my monkey patch is forgotten on the next request, causing all of the tests that I need to stub to fail.

Ideally, I would like to be able to erase the class cache in an After('@tag') method, if this is possible. How can I accomplish that? Or is there a better way of stubbing out certain methods in certain scenarios that I am overlooking?

Sean Hill
  • 14,978
  • 2
  • 50
  • 56

3 Answers3

2

You could take inspiration from this great SO answer, and make good use of ActionDispatch::Callbacks.

Community
  • 1
  • 1
apneadiving
  • 114,565
  • 26
  • 219
  • 213
  • 1
    Okay, I didn't use the Dispatcher callback, but what I did was create a method called reload which I call in `After('@tag') do` which loads the two files which contain the classes which I monkey patched. For example, `load "#{Rails.root}/app/controllers/application_controller.rb"`. Now when my non-stubbed tests run, they run without the monkey patches. Thanks for the help! – Sean Hill Sep 14 '11 at 20:16
  • Just beware of something: when you reload a class, changes and add-ons will be taken into account but not deletions. – apneadiving Sep 14 '11 at 20:17
  • Okay, thanks for the heads-up. I don't think my test stubbing methods are going to change, so as it stands now, this does the job. – Sean Hill Sep 14 '11 at 20:33
0
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader.prepare!

I posted the rationale behind this over here: Why does code need to be reloaded in Rails 3?

If its bad to cross post the same answer, kindly let me know how its preferred to post an answer thats relevant to two questions...I'm happy to oblige.

Community
  • 1
  • 1
Peter P.
  • 3,221
  • 2
  • 25
  • 31
0

As of newer Rails (> 4.0), I was able to reload class definitions, in console, for instance, with reload!.

lucasarruda
  • 1,462
  • 1
  • 25
  • 45