2014-08-29 32 views
7

如何從Ruby的內存中完全刪除一個類?如何在Ruby中重置類定義?

我有兩個文件,我的工作:

# foo.rb 
require 'expensive_library' 

class Foo < ExpensiveLibrary::Plugin 
    ... 
end 

和:

# foo_tests.rb 
require 'foo' 
require 'test/unit' 

class foo_tests < Test::Unit::TestCase 
    def test_foo_meets_spec_1 
    ... 
    end 
    def test_foo_meets_deprecated_spec 
    ... 
    end 
end 

ExpensiveLibrary是昂貴的;加載需要15秒以上。在開發過程中反覆運行測試的時間太長(測試套件的其餘部分時間不到1秒)。

我已經通過啓動Pry並編寫加載這兩個文件並調用Test::Unit:Autorunner.run的函數來解決昂貴庫的加載時間問題。在測試的第一次運行中,這仍然有15秒的停頓,但後續的測試每次只需不到1秒鐘。

但是,這裏有兩個問題:

  1. 撬抱怨在Foo和Foo_tests被重新定義
  2. 當我從刪除源文件的方法有關的所有方法,但它仍然在我的測試環境中定義,產生虛假故障。

基於其他堆棧溢出的問題(如 「How to undefine class in Ruby?」),我已經打過電話Object.constants.remove(:Foo)Object.constants.remove(:Foo_tests)。我不再重新定義錯誤的方法,但現在自動運行程序多次運行測試,包括刪除的測試。

我想要的是在不重新加載ExpensiveLibrary的情況下運行修改後的測試。定義測試類是我看到的方式,但我不知道如何。其他解決方案可能會更好。

+0

感謝您的編輯。 – 2014-08-29 17:50:24

回答

0

好的,只是在這裏吐了口水,因爲我不確定你到底想要什麼,但你試過undef還是undef_method?他們不直接在類上工作,但是如果你解開調用你不想做的測試的方法,它可能適用於你?

0

你可以用加載路徑破解(Adding a directory to $LOAD_PATH (Ruby))。

  • 創建像./tests/fake_implementations/
  • 一些文件夾,將其添加到$ LOAD_PATHS
  • 加有文件expensive_library.rb一些輕量級的假執行ExpensiveLibrary
  • 然後require 'expensinsive_library'將加載,而不是原來的一個文件。
1

在我看來,你正在尋找的是一個預加載,如,甚至更具體的一個像rspec-preloader。當使用預加載器,你將不得不需要在spec/spec_helper.rb文件的「富」的文件,您可能已經有:

# spec/spec_helper.rb 
require 'foo' 

# ... 

spec_helper應該加載你的整個應用環境。可以說,一次運行一個測試時,它更加昂貴。但是通過使用預加載器,您只需要要求所有代碼一次