Модульное тестирование простого использования RACSignal с RACSubject

(Я могу использовать это совершенно неправильно, поэтому не стесняйтесь оспаривать предпосылку этого поста.)

У меня есть маленькийПриложение RACTest (звучит знакомо?) что я пытаюсь провести юнит тест. Я хотел бы проверитьMPSTicker, один из компонентов на основе ReactiveCocoa. Он имеет сигнал, который отправляет значение один раз в секунду, которое накапливается, если флаг накопления установлен на ДА. ядобавил инициализатор принимать пользовательский сигнал для его возрастающего сигнала, а не только на основе таймера.

Я хотел провести модульное тестирование нескольких вариантов поведения MPSTicker:

Убедитесь, что его сигнал накопления увеличивается должным образом (то есть монотонно увеличивается), когда накопление включено, и входной инкрементный сигнал отправляет новое значение.Убедитесь, что он отправляет то же значение (а не увеличенное значение), когда входной сигнал отправляет значение.

я добавилтест, который использует встроенный таймер для проверки первого приращения, и это работает, как я ожидал (хотя я ищу совет по улучшению тупой инициализации RACSequence, которую я сделал, чтобы получить сигнал с@(1) значение, которое я хотел.)

Мне было очень трудно выяснить, какой входной сигнал я могу предоставить MPSTicker, на который я могу вручную отправлять значения. Я предполагаю тест как:

<set up ticker>
<send a tick value>
<verify accumulated value is 1>
<send another value>
<verify accumulated value is 2>

Я пытался с помощьюRACSubject так что я могу использоватьsendNext: подталкивать значения, как я считаю нужным, но это не работает, как я ожидаю. Вот два сломанных теста:

- (void)testManualTimerTheFirst
{
    // Create a custom tick with one value to send.
    RACSubject *controlledSignal = [RACSubject subject];
    MPSTicker *ticker = [[MPSTicker alloc] initWithTickSource:controlledSignal];
    [ticker.accumulateSignal subscribeNext:^(id x) {
        NSLog(@"%s value is %@", __func__, x);
    }];

    [controlledSignal sendNext:@(2)];
}

- (void)testManualTimerTheSecond
{
    // Create a custom tick with one value to send.
    RACSubject *controlledSignal = [RACSubject subject];
    MPSTicker *ticker = [[MPSTicker alloc] initWithTickSource:controlledSignal];

    BOOL success = NO;
    NSError *error = nil;
    id value = [ticker.accumulateSignal asynchronousFirstOrDefault:nil success:&success error:&error];

    if (!success) {
        XCTAssertTrue(success, @"Signal failed to return a value. Error: %@", error);
    } else {
        XCTAssertNotNil(value, @"Signal returned a nil value.");
        XCTAssertEqualObjects(@(1), value, @"Signal returned an unexpected value.");
    }

    // Send a value.
    [controlledSignal sendNext:@(1)];
}

ВtestManualTimerTheFirstЯ никогда не вижу значения отcontrolledSignal«ssendNext: подойди к моемуsubscribeNext: блок.

ВtestManualTimerTheSecondЯ пытался использоватьasynchronousFirstOrDefault: вызов, чтобы получить первое значение из сигнала, затем вручную отправил значение по моей теме, но значение не пришло, и тест не прошел, когдаasynchronousFirstOrDefault: время вышло.

Что мне здесь не хватает?

Ответы на вопрос(2)

Ваш ответ на вопрос