Wrapping a Context in a Context (in RSpec)

14 Mar 2007

A few days ago I blogged about solving a sticky problem by overwriting the “new” method on an ActiveRecord object inside a test (spec). Something I should have mentioned is that this is dangerous because if another spec (test) tries to call new and gets executed after the dangerous spec/test is run, then of course it won’t have the original new method. And it’s a very hard error to track down unless you know it’s been redefined. The solution to this, should you need to do it (and you probably won’t – any good mocking framework will probably do what you want), is to wrap a context around all the contexts that need it and use context_setup like this:

context ‘When the situation demands it’ do
context_setup do
Class SomeObject
def some_method_to_overwrite
#do whatever I want – Bwaa ha ha!
end
end
end

context ‘Some context’ do
#specs go here
end

context ‘Some other context’ do
#more specs go here
end
end

After it drops out of the context, the method isn’t redefined anymore. Yeah! Of course, to be real good and safe you should probably alias the new method in the setup and reassign it back in the teardown. But this works too.