Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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:

  1. Edit your Podfile and add a lines to import OCMock.

    target 'YourProjectTests' do
        pod 'OCMock'
    end
    
  2. Add import in your unit test class

    #import <OCMock/OCMock.h>
    
  3. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top