Posted at

singletonをMockする方法(Kifなどのインテグレーションテスト書くときに便利)

More than 5 years have passed since last update.

iOSでintegration testを書きたいけど、Facebook SDKのログインフローでつまずいてテストが書けない

こういうときに便利!


手段


  1. categoryで、既存のメソッドを書き換える


  2. method_exchangeImplementationsでクラスのメソッドを書き換える

-> categoryで既存のメソッドを書き換えるのが簡単だし分かりやすい


実装方法


  • KIFでfacebookログインボタンが押されたときに、FacebookのopenWithBehaviorのメソッドが実行されるか

@interface WelcomeViewController () 

- (IBAction)authenticateAction;

@end

@implementation WelcomeViewController

#pragma mark - IBActions

- (IBAction)authenticateAction
{
self.session = [[FBSession alloc] initWithAppID:kFacebookAppID permissions:kFacebookPermissions urlSchemeSuffix:kFacebookUrlSchemeSuffix tokenCacheStrategy:nil];

[self.session openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
//login code
}];
}

@end

static id mockSession = nil;

@implementation FBSession (UnitTests)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

- (instancetype)initWithAppID:(NSString *)appID
permissions:(NSArray *)permissions
urlSchemeSuffix:(NSString *)urlSchemeSuffix
tokenCacheStrategy:(FBSessionTokenCachingStrategy *)tokenCachingStrategy {
return mockSession;
}

#pragma clang diagnostic pop

@end

@interface WTDLoginFlowTest : KIFTestCase

@end

@implementation WTDLoginFlowTest

- (void)testSuccessfulLogin
{
mockSession = [OCMockObject mockForClass:[FBSession class]];

[[mockSession expect] openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView completionHandler:nil];

[tester tapViewWithAccessibilityLabel:@"登録・ログイン"];
}
@end


参考