2010-05-11 41 views
2

我試着爲與日期相關的命名範圍編寫規範。指定範圍的RSpec和存根參數

該規範:

it "should return 6 months of documents" do 
    Date.stub!(:today).and_return(Date.new(2005, 03, 03)) 
    doc_1 = Factory.create(:document, :date => '2005-01-01') 
    Document.past_six_months.should == [doc_1] 
end 

在文檔模型中的命名範圍:

named_scope :past_six_months, 
    :conditions => ['date > ? AND date < ?', Date.today - 6.months, Date.today] 

該規範將失敗,空數組,並在test.log中查詢說明了爲什麼:

SELECT * FROM "documents" WHERE (date > '2009-11-11' AND date < '2010-05-11') 

即它似乎忽略了我的存根日期方法。

但是,如果我使用一個類方法,而不是一個命名範圍,然後將其傳遞:

def self.past_six_months 
    find(:all, :conditions => ['date > ? AND date < ?', Date.today - 6.months, Date.today]) 
end 

我寧願使用命名範圍的做法,但我不明白爲什麼它不工作。

===

在回答@speicher:

謝謝,但時空特警似乎並不在這裏幫助。

it "should return 6 months of documents" do 
    d = Date.new(2005, 03, 01) 
    Timecop.travel(d) 
    doc_1 = Factory.create(:document, :date => '2005-01-01') 
    Document.past_six_months.should == [doc_1] 
end 

繼續傳遞類​​方法方法,但不傳遞給指定範圍。

我懷疑named_scope在實際評估它們之前正在對傳遞的條件進行某種操作,這意味着Date.today從不直接調用。

回答

4

我認爲問題在於Date.today不是在運行時計算的,而是當模型第一次被rails讀取時。嘗試把它放在一個拉姆達:

named_scope :past_six_months, lambda { {:conditions => ['date > ? AND date < ?', Date.today - 6.months, Date.today] } } 
+0

謝謝,這是有效的。 – 2010-05-12 11:10:02

1

節省一些頭痛的問題,並使用Timecop創建一個日期或時間。

+0

(我已回覆作爲我的原始文章的編輯,以便我可以包含代碼)。 – 2010-05-11 22:05:20