Open eximius313 opened 1 year ago
Try moving the final comleter = Completer<bool>();
outside of the fakeAsync
zone.
It's hard to reason about fakeAsync
, but my experience is that you should never rely on anything created inside the fake-async zone to happen, or not happen, unless you are actively elapsing time. Don't trust that anything can cross the zone boundary by itself, because that requires something driving the internal progress.
So, if possible, I try to make sure elapsing is done by code running outside of the fake-async zone (because otherwise we can get a deadlock when nothing elapses to the microtask which should run the async.elapse(...)
, and try to push results outside of the zone as well, to check them there. (But I don't have a pattern that I know will always work.)
thanks @lrhn, this code:
void main() {
test('Should interrupt on timeout', () {
final completer = Completer<bool>();
fakeAsync((async) {
//given
var controller = StreamController<Uint8List>();
const expectedError = 'No response';
//when
result() {
controller.stream.timeout(
Duration(seconds: 5),
onTimeout: (sink) {
print('on timeout!');
sink.close();
},
).listen((event) {
}, onDone: () {
print('onDone');
completer.completeError(Exception(expectedError));
});
return completer.future;
}
//then
expect(result, throwsA(predicate((e) => e is Exception && e.toString() == 'Exception: $expectedError')));
async.elapse(Duration(seconds: 6));
});
});
}
indeed works - although I have no idea why, because for me:
fakeAsync((async) {
was executed, because 'onDone'
was printed on the consolecompleter.completeError(Exception(expectedError));
who should end the future so what's creation of final completer = Completer<bool>();
has to do with it?Kind regards
This test:
passes as expected after 5 seconds. But when I apply FakeAsync:
it displays:
as expeceted, but then test hangs and is interrupted after 30sec by timeout: