有没有办法模拟某些单元测试缺少某个gem,缺少实际卸载然后在测试期间重新安装gem?
我正在编写命令行实用程序,并希望确保我的测试涵盖用户可能没有我支持的所有宝石的情况。例如,我正在使用fsevents - 一个特定于Leopard的用于监视文件系统事件的包 - 它永远不会出现在其他系统上,以及一个纯粹可选的咆哮宝石。
答案 0 :(得分:2)
我曾经使用过我写的名为with_constant_unavailable
的方法。我忘记了确切的细节,但我认为它是这样的:
def with_constant_unavailable(constant_name, &block)
match_data = constant_name.to_s.match(/(?:(.+)::)?(.+)/)
if match_data[2]
owning_module, constant_name = match_data[1].constantize, match_data[2]
else
owning_module, constant_name = Object, constant_name.to_s
end
original_constant = owning_module.send :remove_const, constant_name
begin
yield
ensure
owning_module.const_set constant_name, original_constant
end
end
然后你可以像这样进行测试:
def test_uses_foo_when_bar_unavailable
with_constant_unavailable(Bar) do
assert baz.quux == Foo
end
end
答案 1 :(得分:1)
答案 2 :(得分:1)
我会尝试重置gem路径,例如:
require 'rubygems'
Gem.clear_paths
ENV['GEM_HOME'] = ""
ENV['GEM_PATH'] = ""
我也会保存它并在之后恢复它。
答案 3 :(得分:0)
一旦你require
某事,我认为撤消它是非常困难的。但是,您可以执行的操作是一组单独的测试,这些测试始终在单独的Ruby解释器实例中运行,并将它们作为不同的rake
任务调用。所以你可能会有这样的事情:
Rake::TestTask.new(:no_growl_test) do |t|
t.libs << 'lib'
t.pattern = 'test/compatibility/no_growl.rb'
end
这个想法是,这将在一个新的,“干净”的环境中运行,在这种环境中你永远无法加载Growl。其他一些用户提出了一些方法,可以让Rubygems找不到有问题的宝石,甚至可以在Gem API中实现。
或者,使用JRuby创建多个不相交的运行环境并不困难,但这对你正在做的事情来说可能有些过分。