问题
So here's the problem with doing unit tests of calendar code in Objective-C: the Timezone contains the information about daylight savings, so you write a test in the summer, expecting sunrise on June 10th to occur at 6:02 am. Your test passes, later, you are running the test when it's not DST and you get a failure, because when you get the timezone, daylightsavings is turned off.
There doesn't seem to be a simple way to just tell it to give you the timezone with dst turned on?
I was thinking about doing a category so that I would intercept the timezone call but that sounds super messy as I don't know what date you are manipulating.
Of course, I could write all my tests to check the timezone setting and then just shift all my expectations but that sounds like the worst of all possible choices.
回答1:
Region-specific timezones must take into account daylight saving time in order to accurately calculate intervals between two dates (and times). If you aren't interested in this, perhaps you could use a UTC “timezone” instead, which don't change at all.
For example, New Zealand Standard Time is defined as UTC+12:00, and New Zealand Daylight Saving Time is defined as UTC+13:00. Although the local time in New Zealand differs during Daylight Saving Time, the times in UTC+12:00 remain the same (that is, every other country that also uses UTC+12:00 don't magically move forward just because Daylight Saving Time has commenced in New Zealand).
You can achieve this simply by providing that UTC offset as the name:
NSTimeZone *utc_plus12 = [NSTimeZone timeZoneWithName:@"UTC+12:00"];
Find out what UTC offset your region's daylight saving time is based on and use that.
回答2:
I encountered the similar problem. Finally I found OCMock
and saved my life.
If you are using Cocoapods
, that will be great! Here is the steps:
Edit your Podfile and add a lines to import OCMock.
target 'YourProjectTests' do pod 'OCMock' end
Add import in your unit test class
#import <OCMock/OCMock.h>
Write your test case like this
- (void)testLocalTimezoneFromPDT { NSTimeZone* timeZone = [NSTimeZone timeZoneWithAbbreviation:@"PDT"]; id timeZoneMock = OCMClassMock([NSTimeZone class]); OCMStub([timeZoneMock localTimeZone]).andReturn(timeZone); // Implement your test case // XCTAssertEqual(...); }
That code will mock the original [NSTimeZone localTimeZone]
method and return
the static value.
In this example, we return the timezone from Pacific Daylight Time (PDT) [GMT-07:00].
When your class call [NSTimeZone localTimeZone]
, your class will get the timezone we set with OCMock
.
Hopes this answer will help you.
来源:https://stackoverflow.com/questions/14368281/making-nstimezone-trouble-free-in-unit-tests