0

メソッドをテストしています。このメソッドはNSArray、異なるオブジェクトを反復処理する別のメソッドを呼び出します。これらのオブジェクトは、protocol <MNBNotificableTrabel>. このメソッドは、すべてのオブジェクトisKindOfClass: oneClassまたは otherClass をチェックし、1 つを返します。

    for (id <MNBNotificableTravel> travel in self.travelList) {
        if ([travel isGoodForNotification] && [travel notificationType] == MNBNotificableTravelTypeEditable) {
            if ([notificableTravel numberOfPoisOrAssetsForNotification] < [travel numberOfPoisOrAssetsForNotification]) {
                if ([travel isKindOfClass:[MNBNotificableTravelList class]] && !notificableTravel])) {
                    notificableTravel = travel;
                } else if ([travel isKindOfClass:[MNBNotificablePoiListDraft class]]) {
                    notificableTravel = travel;
                } 
            }
        }
    }
    return notificableTravel;
}

それをテストするために、で偽の配列を作成しましたmockedObjectsmockProtocol()それらを区別したいので、を使用せずにさまざまな方法で作成しました。

- (MNBNotificableTravelList *)fakeTravelListGoodForNotification:(BOOL)good numberOfPois:(NSUInteger)numberOfPois type:(MNBNotificableTravelType)type travelId:(NSString *)travelId {
    MNBNotificableTravelList * fakeTravel = mock([MNBNotificableTravelList class]);
    [given([fakeTravel isGoodForNotification]) willReturnBool:good];
    [given([fakeTravel notificationType]) willReturnInteger:type];
    [given([fakeTravel numberOfPoisOrAssetsForNotification]) willReturnInteger:numberOfPois];
    [given([fakeTravel travelID]) willReturn:travelId];
    return fakeTravel;
}

- (MNBNotificablePoiListDraft *)fakePoiListDraftGoodForNotification:(BOOL)good numberOfPois:(NSUInteger)numberOfPois type:(MNBNotificableTravelType)type travelId:(NSString *)travelId {
    MNBNotificablePoiListDraft * fakeTravel = mock([MNBNotificablePoiListDraft class]);
    [given([fakeTravel isGoodForNotification]) willReturnBool:good];
    [given([fakeTravel notificationType]) willReturnInteger:type];
    [given([fakeTravel numberOfPoisOrAssetsForNotification]) willReturnInteger:numberOfPois];
    [given([fakeTravel travelID]) willReturn:travelId];
    return fakeTravel;
}

- (void)testBuildLocalNotificationShouldCallScheduleMethodFourTimes {
    NSDate *installationDate = [NSDate date];
    [given([self.mockUserDefaults boolForKey:mnbUserHasAuthorizedLocation]) willReturnBool:YES];
    [given([self.mockUserDefaults objectForKey:mnbInstallationDateKey]) willReturn:installationDate];
    [given([self.mockDateGenerator notificationDatesForScheduleLifeCycleNotifications]) willReturn:[self fakeNotificationDatesWithInstallationDate:installationDate]];
    NSArray *fakeTravels = @[[self fakePoiListDraftGoodForNotification:YES numberOfPois:3 type:MNBNotificableTravelTypePublished travelId:@"1"],
                             [self fakePoiListDraftGoodForNotification:YES numberOfPois:3 type:MNBNotificableTravelTypeEditable travelId:@"3" ]];

    MNBLifeCycleNotificationBuilder *customSut = [[MNBLifeCycleNotificationBuilder alloc] initWithUserDefaults:self.mockUserDefaults application:self.mockApplication travelList:fakeTravels];
    [customSut buildLocalNotifications];
    [verifyCount(self.mockApplication, times(4)) scheduleLocalNotification:instanceOf([UILocalNotification class])];
}

私の問題は、これを繰り返し処理するときに発生します。NSArray入力すると出力が正しく、 orpo travelのモックであることがわかりますが、入力すると出力は常に になります。MNBNotificableTravelListMNBNotificablePoiListDraftpo [travel isKindOfClass:[MNBNotificableTravelList class]]nil

[isKindOfClass:]を使用して応答を追加しようとしましたgiven。しかし、これは良い方法ではないと思います。応答は 16 進数です。

これを正しくテストする方法を誰もが知っています。

ありがとうございました

4

1 に答える 1

0

解決策 1: コードで isKindOfClass を使用しないでください。イントロスペクションはクールですが、ほとんどの場合、使用しない方が良い方法です。すべてのエントリが準拠するプロトコルのメソッドを使用してロジックを統合したり、 Inversion Of Control のようなパターンを使用したりできます。それに基づいて切り替えます。

解決策 2: isKindOfClass: のモック/オーバーライドは問題ないはずです。これらはモック オブジェクトであり、非標準的な方法で動作するはずです。isKindOfClass : および isMemberOfClass: の NSObject ドキュメントを見て、モック オブジェクトでそれらをオーバーライドします。

于 2015-03-16T16:21:00.553 に答える