2011-08-01 101 views
2

比方說,我們有一些像這樣的代碼:複雜阿雷爾查詢和RSpec磕碰

def index 
    @posts = Post.where(:status => ACTIVE) 
    if params[:s] 
    @posts = Post.where("title like ?", "%#{params[:s]}%").order("title asc") 
    else 
    @posts = Post.limit(20).order("date desc") 
    end 
end 

當間距標準這一行動,我們既可以寫一個短鏈的每一個例子,但這種方式限制了我們很多,如果我們想專注於別的地方。

當您不知道順序或將調用多少個方法時,爲RSpec存根複雜的Arel查詢的最佳方式是什麼?

注意:我正在尋找Stubbing Chained Queries in Rails 3 and Rspec,我想我想要的是類似於stub_chain_with_indifferent_order(:where, :order, :limit)

+0

如果您確實想要查詢規格,那麼對它們進行標記通常是錯誤的答案。你想測試行爲,而不是你給該方法的參數。用數據加載你的數據庫,然後**對數據運行查詢,然後檢查它是否真的符合你的標準。 –

+1

我想要做的就是測試像「應該分配@posts」或「在@posts每個帖子中渲染一個li」這樣的內容,其中stubbing對避免數據庫開銷非常有用。 – Kostas

回答

2

這可能是代碼告訴你,你在錯誤的水平上做這件事。我真的很喜歡RSpec的MOCK ALL THINGS(!!)哲學:如果它很難模擬,也許你的設計是錯誤的。

例如,我可能會重構代碼是:

def index 
    @posts = Post.posts_for(:like => params[:s], :order => (params[:s] ? "title asc" : "date desc") 
end 

(或什麼的稍微好一點的給你的域名。)

然後你就可以模擬出Posts.posts_for,一個簡單的方法調用,而不是試圖模擬大量的AR鏈式方法。

+3

我喜歡你從這裏來的地方,但是我覺得做一個全方位的方法有點不舒服。 arel(我不會主張或對抗,它僅僅是我已經交給的DSL)的整個想法是,您通過方法調用所闡述的增量行爲單位來驅動查詢。這就是說,我會同意我的代碼看起來有點臭,並且正在丟失我的應用程序試圖解決的問題的一些領域語言。 –