2015-05-15 2 views
1

Так что мне нужно проверить, отправлен ли NSNotification. Я попробовал следующий код, чтобы подсмотреть аргумент.Тестирование NSNotification в Kiwi iOS

[[NSNotificationCenter defaultCenter] stub:@selector(postNotification:)]; 

__block KWCaptureSpy *notificationSpy = [[NSNotificationCenter 
defaultCenter] captureArgument:@selector(postNotification:) atIndex:0]; 

[[theValue(notificationSpy.argument.name) should] equal:theValue(SOME_NOTIFICATION)]; 

но проблема с этим связана с тем, что он асинхронен, аргумент не всегда фиксируется перед тестированием. Я не могу добавить shouldEventually для имени notificationSpy.argument.name либо, поскольку он выдает NSInternalConsistencyException для доступа к аргументу перед захватом.

Я также пробовал, [[SOME_NOTIFICATION should] bePosted]; и он потерпел неудачу также.

ответ

3

Вы можете использовать expectFutureValue(), если вы ожидаете, что уведомление будет отправлено когда-нибудь в будущем:

[[expectFutureValue(((NSNotification*)notificationSpy.argument).name) shouldEventually] equal:@"MyNotification"]; 

Вы также не получите NSInternalConsistencyException исключение, так как киви, кажется, работает хорошо с шпионами еще не решен, если они упакованы внутри expectFutureValue.

Другие альтернативы было бы

  • stubsendNotification: метод и «вручную» захватить отправленное уведомление:

    __block NSString *notifName = nil; 
    [[NSNotificationCenter defaultCenter] stub:@selector(postNotification:) withBlock:^id(NSArray *params) { 
        NSNotification *notification = params[0]; 
        notifName = notification.name; 
        return nil; 
    }]; 
    [[notifName shouldEventually] equal:@"TestNotification"]; 
    
  • написать собственный Искателя, который регистрирует в центр уведомлений и утвердить на что сопоставитель:

    [[[NSNotificationCenter defaultCenter] shouldEventually] sendNotification:@"MyNotification"]]; 
    

Лично я бы пошел с пользовательским подходом, более элегантным и более гибким.

+0

Я все еще получаю исключение NSInternalConsistencyException, даже когда я использую expectFutureValue, как вы уже упоминали. – Vig

+0

Кроме того, просто интересно, как вы будете следить за несколькими уведомлениями? скажем, я опубликовал два разных уведомления notificationSpy.argument.name будет иметь только первое право, как бы я шпионить за вторым? – Vig

+0

Хм ... Я проверил код, прежде чем отправлять его, и это сработало для меня. Какой SDK вы используете? – Cristik

1

Возможно, мне не хватает контекста, потому что вы не объяснили тестируемый код. Вы отправляете уведомление? Или вы пытаетесь утверждать, что IOS Framework отправляет вам уведомление? Несмотря на это, здесь есть проблемы, которые я вижу с вашим подходом:

  1. Вы должны выполнить действие, которая отправляет уведомление после шпионил на селекторе postNotification и ДО вы утверждаете значение осматривали аргумента. Из кода, который вы опубликовали, неясно, что это происходит.

  2. Это решение СЛЕДУЕТ работать, если действительно вызывается метод postNotification. На самом деле я не думаю, что это асинхронная проблема. Я часто просматриваю postNotificationName: object: userInfo: в центре по умолчанию с успехом и без специального кода обработки async.

  3. Для проверки равенства строк в киви не обертывайте их в значениеValue(). theValue() используется для проверки равенства по скалярным свойствам. Ваше утверждение должно выглядеть следующим образом:

    [[((NSNotification*)notificationSpy.argument).name should] equal:@"myNotificationName"]; 
    

Если это не поможет получить вам ваше решение, пожалуйста, предоставить больше кода методов, которые вы тестируете и методы испытаний во всей их полноте, а также любые другая полезная информация.

+0

Огромное спасибо, я последовал тому же, и, как уже упоминалось, я получаю NSInternalConsistencyException, поскольку аргумент еще не был обнаружен. – Vig