mardi 5 avril 2016

Unit testing of singleton and the understanding of OCMock stubbing

I've added analytics in my app to track user interaction i.e. when someone clicks on a button, this info is passed into an analytics singleton and sent to our backends.

Here is the current architecture:

viewModel -> SiteAnalytics -> AnalyticsSingleton

Here is some sample code for the vieModel:

 - (void)navigateToScreeOne {
            [self.analyticsHandler buildAnalyticsForScreen:@"one"];
    }

This method is added as a selector to a button in the apps navigation bar.

Here is code for the SiteAnalytics Class:

-(void)buildAnalyticsForScreen:(NSString *)screenNumber{
    NSMutableDictionary *contextualData = [NSMutableDictionary new];
    contextualData[@"feature"] = screenNumber;
    NSString *action = @"screenOne.click";
    [[Analytics sharedInstance] trackAction:action data:contextualData];
}

Here is the code for the Analytics Singleton:

+ (Analytics*)sharedInstance {
    static Analytics *_sharedClient = nil;
    static dispatch_once_t oncePredicate;

    dispatch_once(&oncePredicate, ^{
        _sharedClient = [[self alloc] init];
        [_sharedClient instantiate];
    });
    return _sharedClient;
}

- (void) trackAction:(NSString *)action data:(NSDictionary *)data {
    //This does relevant processing on the data and sends the data to our backends.
}

Now my question is, what would be the best way to do unit test for the buildAnalyticsForScreen method?

I have the following for the tests:

- (void)setUp {
    [super setUp];
    self.analyticsClassUnderTest = [SiteAnalytics new];
    self.analyticsSingleton = [Analytics sharedInstance];
    mockAnalytics = OCMPartialMock(self.analyticsSingleton);
}

- (void)tearDown {
    OCMVerifyAll(mockAnalytics);
    [super tearDown];
}

- (void)testAnalyticsForNavigationToScreenOne {
    NSMutableDictionary *expectedData = [AnalyticsGeneratedData generateContextualDataForNavigationScreenOne];
    OCMExpect([mockAnalytics trackState:@"screenOne.click" data:expectedData]);
    [self.analyticsClassUnderTest buildAnalyticsForScreen:@"one"];
}

I would like to know: 1) If partially mocking the Analytics Singleton is correct? 2) If I should be stubbing the [[Analytics sharedInstance] trackAction:action data:contextualData] method and if so, how?

My rationale here was to make sure that the TrackAction method was called inside the buildAnalyticsForScreen and that the data placed inside of the method is correct, hence the OCMExpect. However, I am uncertain about these things. Any clarity would be appreciated.

Aucun commentaire:

Enregistrer un commentaire