有沒有什麼方法可以模擬某些單元測試中缺少寶石,在測試過程中實際卸載然後重新安裝寶石?在Ruby單元測試中模擬缺失的寶石
我正在編寫一個命令行實用程序,並且希望確保我的測試涵蓋了用戶可能不具備我支持的所有寶石的情況。例如,我正在使用fsevents(一個Leopard特定的軟件包來監視文件系統事件),這種軟件永遠不會出現在其他系統上,以及純粹可選的咆哮寶石。
有沒有什麼方法可以模擬某些單元測試中缺少寶石,在測試過程中實際卸載然後重新安裝寶石?在Ruby單元測試中模擬缺失的寶石
我正在編寫一個命令行實用程序,並且希望確保我的測試涵蓋了用戶可能不具備我支持的所有寶石的情況。例如,我正在使用fsevents(一個Leopard特定的軟件包來監視文件系統事件),這種軟件永遠不會出現在其他系統上,以及純粹可選的咆哮寶石。
我想嘗試重置寶石路,是這樣的:
require 'rubygems'
Gem.clear_paths
ENV['GEM_HOME'] = ""
ENV['GEM_PATH'] = ""
我還要將它保存和事後恢復。
我曾經使用我寫的方法叫做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
一旦你require
d東西,我認爲這是很難解開這個問題。但是,您可以執行的操作有一組獨立的測試,它們始終在單獨的Ruby解釋器實例中運行,並將它們作爲不同的rake
任務調用。所以,你可能有這樣的事情:
Rake::TestTask.new(:no_growl_test) do |t|
t.libs << 'lib'
t.pattern = 'test/compatibility/no_growl.rb'
end
的想法是,這將在一個新的,「乾淨」的環境中,你永遠無法加載低吼運行。其他一些用戶提出了一些方法,可以讓Rubygems找不到有問題的gem,這甚至可能在Gem API中可能。
另外,使用JRuby創建多個不相交的運行環境並不困難,但這可能是對你正在做的事情過度殺傷。
通過路徑確實可以防止寶石加載,但我顯然沒有正確恢復:http://pastie.org/932093 任何提示? 它看起來好像在正確的軌道上: Gem :: clear_paths:「重置+ dir +和+ path +值。下一次+ dir +或+ path +被請求時,這些值將從頭開始計算。 *這主要用於單元測試以提供測試隔離。*「 – 2010-04-23 19:57:28