I've been trying to test a new Rails plugin (stay tuned!), and I've found that I need to have certain Modules unavailable. This is useful when you need to test that missing Modules will raise errors or if you have behavior conditional on what gems are installed.
I wanted something like:
...
with_modules_unavailable(Foo, Bar::Baz::Goo) do
test stuff
end
To get this working, just put the following in your test_helper.rb (this version requires Inflector):
Module.class_eval do
def defining_module
chain = self.to_s.split(/\:\:/)
chain.pop
if chain.empty?
Object
else
chain.join('::').constantize
end
end
def simple_name
self.to_s.split(/\:\:/).pop
end
end
Test::Unit::TestCase.class_eval do
def with_modules_unavailable(*mods, &block)
Thread.exclusive do
mods.each do |mod|
mod.defining_module.send :remove_const, mod.simple_name.to_sym
end
yield block
mods.reverse.each do |mod|
mod.defining_module.send :const_set, mod.simple_name.to_sym, mod
end
end
end
end
You can test that it works with:
def test_with_modules_unavailable
with_modules_unavailable(ActiveRecord::Base) do
assert_raise(NameError) { ::ActiveRecord::Base.class_eval { } }
end
assert_nothing_raised { ::ActiveRecord::Base.class_eval { } }
end
No comments:
Post a Comment