Модульное тестирование простого использования 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:
время вышло.
Что мне здесь не хватает?