Last active
August 29, 2015 14:01
-
-
Save jonnolen/f90668d795ec32461f24 to your computer and use it in GitHub Desktop.
Example of mocking [NSNotificationCenter defaultCenter]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface DTClassToTest : NSObject{ | |
id notificationObserver; | |
} | |
@property (strong, nonatomic) NSNotificationCenter *notificationCenter; | |
@property (assign, nonatomic) BOOL receivedNotification; | |
@end | |
@implementation DTClassToTest | |
-(id)init{ | |
return [self initWithNotificationCenter:[NSNotificationCenter defaultCenter]]; | |
} | |
-(id)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter{ | |
if (!(self = [super init])) return self; | |
_notificationCenter = notificationCenter; | |
_receivedNotification = NO; | |
return self; | |
} | |
- (void)registerForNotifications{ | |
id __weak wself = self; | |
notificationObserver = [self.notificationCenter addObserverForName:@"CONTRIVED_NOTIFICATION" | |
object:nil | |
queue:[NSOperationQueue mainQueue] | |
usingBlock:^(NSNotification *n){ | |
DTClassToTest *self = wself; | |
self.receivedNotification = YES; | |
}]; | |
} | |
- (void)dealloc{ | |
[_notificationCenter removeObserver:notificationObserver]; | |
} | |
@end | |
@interface DTClassToTestTests : XCTestCase{ | |
DTClassToTest *objectUnderTest; | |
NSNotificationCenter *testNotificationCenter; | |
} | |
@end | |
// If you can inject notification center into a class for tests, then this is the best way to do this | |
@implementation DTClassToTestTests | |
- (void)setUp{ | |
[super setUp]; | |
testNotificationCenter = [NSNotificationCenter new]; | |
objectUnderTest = [[DTClassToTest alloc] initWithNotificationCenter:testNotificationCenter]; | |
} | |
- (void)test_responds_to_notification_correctly{ | |
[objectUnderTest registerForNotifications]; | |
[testNotificationCenter postNotificationName:@"CONTRIVED_NOTIFICATION" object:nil]; | |
XCTAssertTrue(objectUnderTest.receivedNotification); | |
} | |
@end | |
@interface DTClassToTestTestsTheClassMockWay : XCTestCase{ | |
DTClassToTest *objectUnderTest; | |
NSNotificationCenter *testNotificationCenter; | |
id mockCenter; | |
} | |
@end | |
// if there is no injection point, you can use OCMock to mock the defaultCenter class method. but you need to explicitly call | |
// stopMocking in your test tearDown. | |
@implementation DTClassToTestTestsTheClassMockWay | |
- (void)setUp{ | |
[super setUp]; | |
testNotificationCenter = [NSNotificationCenter new]; | |
mockCenter = [OCMockObject niceMockForClass:NSNotificationCenter.class]; | |
[[[[mockCenter stub] classMethod] andReturn:testNotificationCenter] defaultCenter]; | |
objectUnderTest = [DTClassToTest new]; // Will use [NSNotificationCenter defaultCenter]; | |
} | |
- (void)tearDown{ | |
[mockCenter stopMocking]; //if you omit this line in your tear down, your tests will not finish. | |
[super tearDown]; | |
} | |
- (void)test_responds_to_notification_correctly{ | |
[objectUnderTest registerForNotifications]; | |
[testNotificationCenter postNotificationName:@"CONTRIVED_NOTIFICATION" object:nil]; | |
XCTAssertTrue(objectUnderTest.receivedNotification); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment