Unit-Test einer einfachen Verwendung von RACSignal mit RACSubject

(Ich verwende dies möglicherweise auf eine völlig falsche Weise. Sie können die Prämisse dieses Beitrags also jederzeit in Frage stellen.)

ich habe einen kleinenRACTest App (klingt bekannt?), dass ich versuche, Unit-Test. Ich würde gerne testenMPSTicker, eine der am meisten auf ReactiveCocoa basierenden Komponenten. Es hat ein Signal, das einmal pro Sekunde einen Wert sendet, der sich akkumuliert, wenn ein Akkumulationsflag auf JA gesetzt ist. ichhat einen Initialisierer hinzugefügt ein benutzerdefiniertes Signal für sein inkrementierendes Signal zu nehmen, anstatt nur auf einem Timer zu basieren.

Ich wollte ein paar Verhaltensweisen von MPSTicker testen:

Stellen Sie sicher, dass das Akkumulationssignal ordnungsgemäß inkrementiert wird (d. H. Monoton ansteigt), wenn die Akkumulation aktiviert ist und das Eingangsinkrementierungssignal einen neuen Wert sendet.Stellen Sie sicher, dass derselbe Wert (und kein inkrementierter Wert) gesendet wird, wenn das Eingangssignal einen Wert sendet.

Ich habe hinzugefügtEin Test, der den eingebauten Timer verwendet, um das erste Inkrement zu testen, und es funktioniert wie erwartet (obwohl ich Rat zur Verbesserung der RACSequence - Initialisierung suche, die ich durchgeführt habe, um ein Signal mit dem zu erhalten)@(1) Wert, den ich wollte.)

Ich hatte große Schwierigkeiten herauszufinden, welches Eingangssignal ich MPSTicker zur Verfügung stellen kann, an das ich manuell Werte senden kann. Ich stelle mir einen Test vor wie:

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

Ich habe versucht mit einemRACSubject also kann ich benutzensendNext: Werte nach meinem Ermessen einbringen, aber es funktioniert nicht so, wie ich es erwartet habe. Hier sind zwei kaputte Tests:

- (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)];
}

ImtestManualTimerTheFirstIch sehe nie einen Wert voncontrolledSignal'ssendNext: komm zu mir durchsubscribeNext: Block.

ImtestManualTimerTheSecondIch habe versucht mit derasynchronousFirstOrDefault: Rufen Sie an, um den ersten Wert aus dem Signal abzurufen, und senden Sie dann manuell einen Wert zu meinem Betreff, aber der Wert ist nicht angekommen, und der Test ist fehlgeschlagen, alsasynchronousFirstOrDefault: Zeitüberschreitung

Was vermisse ich hier?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage