Saturday 13 May 2017

Warten Sieerwartungenwithtimeout Handlery

In meiner Unit-Tests, Ich bin mit der - XCTestCase keyValueObservingExpectationForObject: keyPath: Handler: Methode, um sicherzustellen, dass meine NSOperation beendet ist, ist hier der Code aus meinem XCDYouTubeKit Projekt: Dieser Test immer passiert, wenn ich es lokal auf meinem Mac, aber manchmal ausführen Es fehlschlägt auf Travis mit diesem Fehler: failed: gefangen NSRangeException, kann keinen Beobachter entfernen ltXCKVOExpectation 0x1001846c0gt für den Schlüsselpfad isFinished von ltXCDYouTubeVideoOperation 0x1001b9510gt, da er nicht als Beobachter registriert ist. Bin ich etwas falsch gemacht Dein Code ist richtig, du hast einen Fehler im XCTest Framework gefunden. Hier ist eine ausführliche Erklärung, können Sie zum Ende dieser Antwort überspringen, wenn Sie nur auf der Suche nach einem Workaround sind. Wenn Sie keyValueObservingExpectationForObject: keyPath: handler aufrufen. Wird ein XCKVOExpectation-Objekt unter der Haube erstellt. Es ist für das Beobachten des objectkeyPath verantwortlich, den Sie überschritten haben. Sobald die KVO-Benachrichtigung ausgelöst hat, wird die Methode safelyUnregister aufgerufen, hier wird der Beobachter entfernt. Hier ist die (reverse engineered) Implementierung der Methode safelyUnregister. Diese Methode wird nochmals am Ende von waitForExpectationsWithTimeout: handler aufgerufen und wenn das XCKVOExpectation-Objekt deallocated wird. Beachten Sie, dass der Vorgang auf einem Hintergrund-Thread beendet wird, aber der Test auf dem Hauptthread ausgeführt wird. Sie haben also eine Racebedingung: Wenn safelyUnregister auf dem Haupt-Thread aufgerufen wird, bevor die Eigenschaft hasUnregistered auf YES auf dem Hintergrund-Thread gesetzt ist, wird der Beobachter zweimal entfernt, was dazu führt, dass eine Beobachter-Ausnahme nicht entfernt werden kann. So, um Problemumgehung dieses Problem, müssen Sie die SafeUnregister-Methode mit einem Schloss zu schützen. Hier ist ein Code-Snippet für Sie, um in Ihrem Test-Ziel zu kompilieren, wird kümmern sich um die Behebung dieses Bug. Ich teste einen asynchronen Aufruf mit XCTestExpectation. Der folgende Code funktioniert (der Test ist erfolgreich), wenn das completionHandler vor dem angegebenen 1 Sekunde Timeout ausgeführt wird. Allerdings, wenn die completionHandler nicht aufgerufen wird und daher die Erwartung nicht erfüllt, anstatt einen Testfehler beim Aufruf von waitForExpectationsWithTimeout bekomme ich eine EXCBADACCESS, die nicht sehr praktisch, da dies macht es unmöglich, die gesamte Test-Suite Ergebnisse sehen. Wie kann ich dieses vermeiden und erhalten einen normalen Testausfall gefragt 21. Dez 14 um 15:31


No comments:

Post a Comment