2011-05-02 56 views
7

我來自Spring/Hibernate背景。我注意到Rails沒有道和服務層。這確實加快了開發速度,但我不知道應該在哪裏進行測試。我在哪裏把我的數據庫查詢測試在軌道上?

現在,我一直在我的模型方法和驗證測試在主模型spec。這個文件已經相當大了。

「標準」測試查詢的地方在哪裏?我可以想象自己製作了大量的燈具/虛擬數據,以確保我的查詢能夠按照預期工作(可能是因爲我是rails新手而更好的想法)。這些對於基本的模型邏輯和驗證測試並不是真的需要。

如果你可以提供一些建議,把這些測試放在哪裏,使用rails測試查詢的最佳方法(特別是帶有多個連接的測試!),也許一些基本的指導方針可能與使用DBunit /春天/冬眠,那會很棒。

謝謝!

+0

不確定「查詢」是什麼意思。在Rails中,最好將數據庫視爲持久對象的地方。 ActiveRecord對象更加精確。 ORM負責所有的數據庫邏輯和SQL。那些不需要被測試,除非你正在做一些違反公約的事情。 – 2011-05-04 14:29:26

+0

@Mike Farmer如果您在請求特定值之前走過對象圖20次,ActiveRecord會在20個表之間創建一個複雜而有效的SQL連接? – egervari 2011-05-09 20:37:43

+0

只要你正確地設置你的關聯,我真的不明白爲什麼不。來自數據庫背景,但我明白你的觀點。編寫測試以確保您的查詢構建正確並具有高性能是您指定的複雜性的好主意。爲您的關聯修改一些finder_sql,counter_sql,delete_sql和insert_sql對於更復雜的查詢也可能會有所幫助。請參閱(http://j.mp/lOSBkh) – 2011-05-12 16:55:13

回答

4

我以前也用過hibernate。 ActiveRecord的方式與hibernate非常不同。你需要放下心靈,無論好壞。在java和Hibernate中,你經常擁有聚合根和對象圖。通常情況下,對象圖和代碼庫在某種程度上都比較小。我不知道你的具體情況,所以我會小心翼翼地行事,但我警告你要嘗試適合ruby和rails,以符合你的java習慣。

您可以使用帶有rspec的自定義目錄以一種對您和您的團隊有意義的方式進行組織。

#spec/queries/my_custom_search_spec.rb 

require 'spec_helper' 
describe MyModel do 
    it "should do this query and return X" do 
    subject.some_defined_scope_search.should == "something" 
    end 
end 

,你可能有子目錄,由rspec的自動得到回升,像spec/models/account/..

該規範將自動被rake specrspec spec回升。我剛剛寫了一個簡單的例子,因爲我不知道你的情況。你是用查詢來定義範圍還是定義專門的方法?

我強烈建議放棄固定裝置(與插入相同 - 反模式,對我來說)爲更可重構的東西,如工廠。我喜歡factory_girl。它讓您的應用以更靈活的方式演變,IMO。

編輯: 加入我的spec_helper.rb具有用於啓用/禁用自動清理

RSpec.configure do |config| 
    require 'database_cleaner' 
    config.add_setting :skip_database_clean 
    config.skip_database_clean = false 
    config.before(:suite) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
    end 

    config.after(:each) do 
    MongoMapper.database.collections.each(&:remove) 
    DatabaseCleaner.clean unless config.skip_database_clean 
    end 

我添加變量skip_database_clean這樣我可以啓用/每規格後禁用autocleanup設置(每個「它」) 。

before :all do 
    @an_object = some_expensive_test_buildup 
    RSpec.configuration.skip_database_clean = true 
    end 
    after :all do 
    RSpec.configuration.skip_database_clean = false 
    DatabaseCleaner.clean 
    end 
+0

是的,我已經在使用工廠女孩了。我發現我需要製作3-4個記錄以及它們的依賴關係,才能正確地測試查詢以確保它們正在工作。因此,測試設置代碼變得非常龐大,因爲我可能需要創建一個小型數據庫來使測試通過並測試所有查詢可能性以確保查詢邏輯正常工作。 – egervari 2011-05-10 09:05:35

+0

運行規格需要多長時間? 您可以在'before:all'中完成測試數據的構建,然後在數據上添加一堆查詢規範。如果您激活了自動清理功能(如DatabaseCleaner),您必須禁用全局'before:each'。 – oma 2011-05-10 09:18:36

+0

實際上,將我的測試移動到新文件夾中似乎會導致rails無法清理乾淨。我需要在環境中的某個地方打開它嗎? – egervari 2011-05-11 13:54:07

0

如果您使用普通導軌ORM,那麼您不會創建查詢,也不需要測試數據訪問。

如果您確實開始編寫自定義SQL查詢,那麼我建議您在執行查詢後使用rspec並測試對象的行爲。

+0

您將如何使用Rails ORM並且不會創建查詢...?我不是在問我應該或不應該測試它們 - 我問「這些測試應該去哪裏?」他們在模型規範中做什麼?完全不同的規格?哪裏?我知道如何測試它們 - 我在問哪裏。 – egervari 2011-05-03 03:10:59

+0

如果您將模型定義爲導軌預期,則不要編寫查詢。你只需:「@ account.purchases」,並返回該帳戶的購買。你可以寫一個規範,說明購買應該屬於某個賬戶,但這就像我去的那樣。 – 2011-05-03 13:10:13

+0

對於很長的對象圖,這是一個很糟糕的做法Jesse。這不是真正的查詢 - 你實際上是從數據庫中刪除數據。這太可怕了。如果你不得不加入20個表來獲得你想要的數據,你真的會走對象圖20次嗎?如果每個集合中有100條記錄,那麼會有100條記錄從數據庫中抽出!不,做這件事的最好方法就是QUERY - 因此是個問題。 – egervari 2011-05-09 20:35:41

1

Rails使用阿雷爾生成你在Ruby代碼通過Rails ActiveRecord關聯的API定義了基於關係數據庫查詢的SQL(假設你使用的ActiveRecord作爲ORM,它是默認的)。如果您認爲可以改進自動生成的內容(可以在日誌文件中看到),則可以編寫自己的SQL。

通常,您將通過模型上的方法調用來調用這些查詢(無論手動還是自動寫入)。例如,@author.books@author.readers;這些可以體現一個連接的查詢。

我不確定手寫查詢的問題,但生成的查詢通常使用一旦完成構建的作用域即可在請求結果時實現。例如,@author.books.order('price').limit(10)。您可以定義自己的自定義範圍。

我會在模型的單元測試中測試自定義查詢或作用域的正確性,因爲它們是模型工作不可或缺的部分。例如,@author.popular_books可能是您的模型中定義的自定義範圍,您可以爲您的Author模型編寫單元測試,以確保它返回某些已知測試數據的預期結果。

+0

實質上,我認爲你在正確的地方有你的測試。也許你可以寫一些測試助手來減少代碼的長度?看看Shoulda測試框架以獲得助手的想法(您不需要實際使用它,但它確實有許多助手來執行常見的事情,如檢查驗證)。 – 2011-05-10 00:07:44

+0

這就是我目前的做法。當我需要進行多個連接時,編寫這些作用域查詢會變得非常痛苦,所以我需要在數據庫中創建大量測試數據來驗證查詢是否正常工作。這經常會膨脹模型規格文件 – egervari 2011-05-10 02:21:51