2017-06-21 3 views
0

Ich habe das Beispiel von hier wieder erstellt: http://www.mokacoding.com/blog/testing-callbacks-in-swift-with-xctest/.Wie löst man einen fehlgeschlagenen Test beim Timeout mit waitForExpectations() aus?

Ich möchte für einen Timeout mit waitForExpectations() testen. Dies sollte einen lang andauernden Prozess nachahmen, der abgelaufen ist. Um dies zu tun, habe ich einen sleep() Befehl in der aufgerufenen Funktion, die länger als die Zeitüberschreitung in waitForExpectations() ist.

Die sleep() hat jedoch keine Wirkung. Der Test besteht immer. Ich habe versucht, sleep() vor completion(true) auch zu setzen, aber das ändert nicht das Ergebnis (d. H. Bestandener Test).

Irgendwelche Ideen, was ich mache, um einen Testfehler bei Timeout auszulösen?

class SomeService { 
    func doSomethingAsync(completion: (_ success: Bool) ->()) { 
     completion(true) 
     sleep(5) 
    } 
} 

In Testklasse

let service = SomeService() 
service.doSomethingAsync { (success) in 
    XCTAssertTrue(success, "assert is true") 
    expect.fulfill() 
} 

waitForExpectations(timeout: 3) { (error) in 
    if let error = error { 
     XCTFail("timeout errored: \(error)") 
    } 
} 

Antwort

1

Ihr Test bestanden wird, weil Sie completion vor sleep anrufen, damit Ihre Erwartung wird fast sofort erfüllt - vor Sie für 5 Sekunden warten; Während der Completion-Block asynchron ausgeführt wird, wird er wahrscheinlich in weniger als einer Sekunde beendet. Wenn Sie sleep innerhalb completion aufrufen, wird Ihr Test wie erwartet fehlschlagen. Ihr Test stürzt jedoch möglicherweise ab, wenn der Test nicht mehr ausgeführt wird, wenn expect.fulfill() aufgerufen wird, da expect zum Zeitpunkt der Ausführung möglicherweise nicht mehr existiert, da er möglicherweise bereinigt wurde, sobald der Test fehlschlägt (ca. 2 Sekunden vor der Erwartung) wird erfüllt werden).

class SomeService { 
    func doSomethingAsync(completion: (_ success: Bool) ->()) { 
     DispatchQueue.main.async { 
      completion(true) 
     } 
    } 
} 

Test:

let service = SomeService() 
service.doSomethingAsync { (success) in 
    XCTAssertTrue(success, "assert is true") 
    sleep(5) 
    expect.fulfill() 
} 

waitForExpectations(timeout: 3) { (error) in 
    if let error = error { 
     XCTFail("timeout errored: \(error)") 
    } 
} 
+0

Wie bereits erwähnt, setzt 'sleep()' 'vor completion' keine Wirkung. – 4thSpace

+0

Ja, das macht Sinn Entschuldigung, ich habe meine Antwort richtig umformuliert - Sie müssen den Schlaf aus dem asynchronen Abschlussblock aufrufen und nicht in doSomethingAsync, was synchron ist, so dass der Schlaf bereits ausgeführt wurde, bevor der Test zu warten beginnt. – Oletha

+0

Wie würdest du das oben beschriebene rekodieren, also wird 'sleep()' in 'completion' aufgerufen? – 4thSpace

Verwandte Themen