2010-04-23 85 views
1

有沒有什麼方法可以模擬某些單元測試中缺少寶石,在測試過程中實際卸載然後重新安裝寶石?在Ruby單元測試中模擬缺失的寶石

我正在編寫一個命令行實用程序,並且希望確保我的測試涵蓋了用戶可能不具備我支持的所有寶石的情況。例如,我正在使用fsevents(一個Leopard特定的軟件包來監視文件系統事件),這種軟件永遠不會出現在其他系統上,以及純粹可選的咆哮寶石。

回答

1

您可以測試常量的存在。

if !defined?(Growl) 
    ... 
end 

在你的測試,你可以暫時rename/disable/remove不斷以模擬缺失的庫。

1

我想嘗試重置寶石路,是這樣的:

require 'rubygems' 
Gem.clear_paths 
ENV['GEM_HOME'] = "" 
ENV['GEM_PATH'] = "" 

我還要將它保存和事後恢復。

+0

通過路徑確實可以防止寶石加載,但我顯然沒有正確恢復:http://pastie.org/932093 任何提示? 它看起來好像在正確的軌道上: Gem :: clear_paths:「重置+ dir +和+ path +值。下一次+ dir +或+ path +被請求時,這些值將從頭開始計算。 *這主要用於單元測試以提供測試隔離。*「 – 2010-04-23 19:57:28

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 
0

一旦你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創建多個不相交的運行環境並不困難,但這可能是對你正在做的事情過度殺傷。