Ask for Help
“Is there a good way to temporarily redefine a method on a controller during a functional test?”
Reopening a controller and overriding a method affects all tests in a suite. Is there a good way to redefine a controller method for a single test?
I would comment that testing your exception handling is one of the primary reasons I use mocks for. You just mock the method that may trigger the exception to actually throw it. See the raises method in mocha (http://mocha.rubyforge.org/classes/Mocha/Expectation.html#M000046)
However, if you must override the method and you have @controller recreated in setup() so it doesn’t affect other tests, then you could do this inside your test method:
@controller.instance_eval do
def overridden_method
end
end
July 22, 2009 at 12:17 pm
Rspec’s mocks can take blocks, if that’s an option for you.
Otherwise, Alex’s instance_eval suggestion or @controller.extend(OverrideMethodModule) are your best choices.
July 22, 2009 at 12:41 pm
Stub it out, as everyone else is saying. T
here are some cases where the complexiity of rspec or mocha stubbing doesn’t work (in my case something to do with a super call), so I made a [quick hack to hide/replace a method for the duration of a block.](http://gist.github.com/152242)
July 22, 2009 at 1:17 pm
def skip_method(klass, action, &block)
method = klass.instance_method(action)
define_method(action) { true }
yield
remove_method(action)
define_method(action, method)
end
That should only replace the action or model method during the scope of the block.
July 22, 2009 at 10:21 pm
Earlier comment: I forgot to mention that mocking is not an option in this case because part of the functionality of the method in question is that it throws an exception.
But mocking can also “throw exceptions”?
Stephan
July 24, 2009 at 5:43 pm
Stephan, yes. Mocha, for instance, can return a value from a stub, or alternatively raise an exception.
July 25, 2009 at 12:11 am
You could mock the method in just the test you care about.
July 22, 2009 at 10:47 am
@Zach- That’s true. I forgot to mention that mocking is not an option in this case because part of the functionality of the method in question is that it throws an exception.
July 22, 2009 at 10:52 am