2012-01-13 16 views
6

sto spec'ing un ambito in un 3.0 app Rails come segue:Utilizzando Timecop gioiello per scopi

class DrawingList < ActiveRecord::Base 
    scope :active_drawings, where('start_date <= ? AND end_date >= ?', Date.today, Date.today) 
end 

Nella mia spec, voglio fare:

before do 
    @list = DrawingList.create #things that include begin and end dates 
end 

it "doesn't find an active drawing if they are out of range" do 
    pending "really need to figure out how to work timecop in the presence of scopes" 
    Timecop.travel(2.days) 
    puts Date.today.to_s 
    DrawingList.active_drawings.first.should be_nil 
end 

come si potrebbe immagina, le mette mostra davvero che Date.today è due giorni quindi. Tuttavia, l'ambito viene valutato in un contesto diverso, quindi utilizza il vecchio "oggi". Come si ottiene oggi una valutazione in un contesto che può influenzare Timecop.

Grazie!

risposta

18

Questo è un errore molto comune. Come hai scritto nella data usata dall'oscilloscopio è la data com'era quando è stato caricato il codice. Dovresti eseguirlo in produzione dove il codice viene ricaricato solo se si riavvia l'app (diversamente dallo sviluppo in cui viene ricaricato su ogni richiesta), si otterranno i risultati corretti il ​​giorno in cui è stata riavviata l'app, ma il giorno successivo i risultati sarebbe fuori di un giorno, il giorno dopo da 2 giorni ecc

il modo corretto di definire una portata del genere è

scope :active_drawings, lambda { where('start_date <= ? AND end_date >= ?', Date.today, Date.today)} 

il lambda garantisce che tali date vengono valutate ogni volta la portata viene utilizzato .

+0

Buona risposta a una buona domanda. –

+0

Questa è una questione delicata da cogliere! Grazie. Sono così felice che ora sono consapevole di questo comportamento. –

Problemi correlati