matcher
matcher copied to clipboard
Add a Timeout to emits()
I want to test if a Stream
doesn't emit anything if a variable is false
, I can't see how to do it with the current API, so a timeout of 1 second should be enough and receiving the timeout should be possible to indicate that the test run successfully.
var subscription = someStream.listen((_) {
fail('Should not emit');
});
await Future.delayed(const Duration(seconds: 1));
await subscription.cancel();
Waiting for a value and waiting for a fixed amount of time for no value are sufficiently different that I'd prefer not to mix it in with emits
. We could add doesNotEmitFor(Duration)
, but a test like this feels like a bit of an antipattern and for the edges where we need to do it I think the few extra lines of code aren't too bad. We wouldn't get any value out of the StreamQueue
stuff as far as I can tell.
cc @grouma for thoughts.
I like the idea of doesNotEmitFor(Duration)
. As an alternative you can do something like this today:
test('timeout test', () async {
var completer = Completer();
expect(completer.future.timeout(Duration(seconds: 1)),
throwsA(TypeMatcher<TimeoutException>()));
});
@grouma can your example be used for Stream
?
@natebosch yeah, I see your point, it does fill a bit of an antipattern, but at the same time doesNotEmitFor(Duration)
sounds useful and not harmful, so why not?
You can use toList()
on a Stream
to likely get the behavior your want. For example:
test('timeout test', () async {
var controller = StreamController();
expect(controller.stream.toList().timeout(Duration(seconds: 1)),
throwsA(TypeMatcher<TimeoutException>()));
});
@grouma thanks, but for my use case, @natebosch solution was better as I had to call a method to trigger the emission.
Thumbs up for doesNotEmitFor
!