matcher icon indicating copy to clipboard operation
matcher copied to clipboard

Add a Timeout to emits()

Open feinstein opened this issue 5 years ago • 6 comments

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.

feinstein avatar Jan 22 '20 21:01 feinstein

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.

natebosch avatar Jan 22 '20 21:01 natebosch

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 avatar Jan 22 '20 21:01 grouma

@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?

feinstein avatar Jan 22 '20 22:01 feinstein

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 avatar Jan 22 '20 22:01 grouma

@grouma thanks, but for my use case, @natebosch solution was better as I had to call a method to trigger the emission.

feinstein avatar Jan 22 '20 22:01 feinstein

Thumbs up for doesNotEmitFor!

HerrNiklasRaab avatar Apr 12 '20 21:04 HerrNiklasRaab