I'm building a serial task sequencer that will be able to synchronize the delivery of several objects to the network.
Any thread in the app can send tasks to the sequencer, and so I want to synchronize the delivery to the sequencer. Because of this, I made the sequencer an actor, and I added to it a function that will add objects to the queue in the sequencer.
I was starting to do TDD to build it, but I got stuck even before starting.
My first approach was to create a test that would wait for the sequencer to stop execution and then would check the state of the mocked network interface afterwards. Because of that, I added a property to the sequencer that tells me whether it's still working.
This test will asynchronously add an object to the sequencer, and then I'd wait until it's done.
This is the code for the sequencer:
final class DefaultSequencer: Sequencer {
let isFinished: Bool = true
func appendObjects(_ objects: [String]) async {
// TODO: This will add to a queue and start processing.
}
}
And this is the code for the test:
final class DefaultSequencerTests: XCTestCase {
private var sut: DefaultSequencer!
override func setUp() {
sut = DefaultSequencer()
}
override func tearDown() {
sut = nil
}
func test_appendObjects_ShouldFinish() async throws {
// Given
let objects = ["1", "2"]
// When
await sut.appendTasks(objects)
// Then
let predicate = NSPredicate { _, _ in
self.sut.isFinished == true
}
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: nil)
await fulfillment(of: [expectation], timeout: 20)
// wait(for: [expectation], timeout: 20)
}
}
This test should pass because by default the isFinished property is set to true.
If I use the fulfillment method, this test won't pass. However, if I use the wait(for:) method it will pass but will show a warning that I shouldn't use that method in an asynchronous scope.
Am I doing this wrong? Am I missing something? Any help would be appreciated.