2010-12-30 1 views
4

Ich möchte Testdaten für eine Anwendung erstellen, und es gibt eine Menge von time_at Attribute verfolgt werden, zu viele, um in einer wartbaren Weise zu überschreiben. Was ich denke ist, kann ich einfach die Basis Referenzzeitvariable in Ruby ändern?Überschreiben Sie, was Ruby denkt, ist die aktuelle Zeit in Time.now?

macht Dies würde es so created_at, updated_at, last_login_at usw., zu einer künstlichen Zeit eingestellt werden kann, so konnte ich dies in Tests durchführen:

Date.today #=> Thu, 30 Dec 2010 
Time.system_time_offset = 1.week.ago # made up 
Date.today #=> Thu, 23 Dec 2010 
Time.now #=> Thu Dec 23 14:08:38 -0600 2010 

user_1 = User.create! 
user_1.created_at #=> Thu Dec 23 14:08:38 -0600 2010 

Time.reset_system_time # made up 

user_2 = User.create! 
user_1.created_at #=> Thu Dec 30 14:08:38 -0600 2010 

Gibt es eine Möglichkeit, dies zu tun?

+1

Dies könnte für Sie nützlich sein: http://stackoverflow.com/questions/714042/unit-testing-code-which-gets-current-time –

+0

Duplikat von http://stackoverflow.com/questions/1215245/ ruby-unit-testing-how-to-fake-zeit-jetzt –

Antwort

7

könnten Sie Mocha verwenden den Rückgabewert von Time.now während eines Tests zu ändern:

 
Time.stubs(:now).returns(Time.now - 1.day) 
+1

RSpec: Time.stub (: jetzt) ​​.and_return (Time.now - 1.day) – clemensp

1

Ehrlich gesagt, ich in der Regel Tests schreiben für aktuelle Zeit zu überprüfen, ob der Zeitstempel innerhalb eines angemessenen Bereichs liegt. Überprüfen Sie, ob der Zeitstempel größer als 1.minute.ago ist. Das Ändern der Systemuhr hat wahrscheinlich alle möglichen unvorhersehbaren Nebenwirkungen, also möchten Sie das nicht tun. Sie können möglicherweise alle Orte in Ruby ausfindig machen, auf die die aktuelle Zeit zugegriffen wird (obwohl ich denke, dass die meisten Methoden nur Time.now verwenden) und sie für die Tests affen - aber ich würde wahrscheinlich immer noch lieber nur den Zeitstempel überprüfen ein vernünftiger Bereich.

+0

+1 "Ändern der Systemuhr wird wahrscheinlich alle Arten haben von unvorhersehbaren Nebenwirkungen ". Bestimmt. –

1

Es ist auch möglich (igitt) monkeypatch Zeit:

$start = Time.now - 86400 # this time yesterday 

class Time 
    class << Time 
    def new 
     $start 
    end 
    def now 
     Time.new 
    end 
    end 
end 

puts(Time.now) 
puts($start) 
3

Ich benutze das timewarp Juwel für diese Art der Sache. Sie setzen Ihren Code einfach in einen pretend_now_is (Zeit) -Block und der Code darin wird ausgeführt, als ob das die tatsächliche Zeit wäre.

http://github.com/harvesthq/time-warp

Hier ist ein Beispiel

def test_should_find_company_needing_reminded_today 
    pretend_now_is(Time.utc(2008,"jul",24,20)) do #=> Thu Jul 24 20:00:00 UTC 2008 
    @company.reminder_day = 'Thursday' 
    @company.save 
    companies = Company.find_companies_needing_reminded_today 
    assert_equal true, companies.include?(@company) 
    end 
end 
+1

Dies ist besser, da es auch "Date.today" betrifft. – lulalala

4

Ein gutes Juwel für diese Timecop ist: https://github.com/travisjeffery/timecop.
Sie können die Zeit einfrieren oder die Zeit (während sie weiterläuft) sehr einfach ändern.

Ex.

Time.now 
# => 2014-03-14 13:17:02 -0400 
Timecop.travel 2.hours.ago 
Time.now 
# => 2014-03-14 11:17:04 -0400 

Sein schöner als die Mokka-Lösung, da alle Zeitfunktionen gleichermaßen betroffen sein werden, so werden Sie nicht einen Test, wo Time.now dann etwas anderes zurückkehr DateTime.now

Es ist auch mehr nach oben bis heute als das in einer anderen Antwort vorgeschlagene Zeitsprung-Juwel.

Verwandte Themen