setMockStreamHandler method
- EventChannel channel,
- MockStreamHandler? handler
Set a handler for intercepting stream events sent to the platform on the given channel.
Intercepted method calls are not forwarded to the platform.
The given handler will replace the currently registered handler for that channel, if any. To stop intercepting messages at all, pass null as the handler.
Events are decoded using the codec of the channel.
The handler's stream messages are used as a response, after encoding them using the channel's codec.
To send an error, pass the error information to the handler's event sink.
It is strongly recommended that all handlers used with this API be
synchronous (not requiring any microtasks to complete), because
testWidgets tests run in a FakeAsync zone in which microtasks do not
progress except when time is explicitly advanced (e.g. with
WidgetTester.pump), which means that await
ing a Future will result
in the test hanging.
Registered handlers are cleared after each test.
See also:
-
setMockMethodCallHandler, which is the similar method for MethodChannel.
-
setMockMessageHandler, which is similar but provides raw access to the underlying bytes.
-
setMockDecodedMessageHandler, which is similar but decodes the messages using a MessageCodec.
Implementation
void setMockStreamHandler(EventChannel channel, MockStreamHandler? handler) {
if (handler == null) {
setMockMessageHandler(channel.name, null);
return;
}
final StreamController<Object?> controller = StreamController<Object?>();
addTearDown(controller.close);
setMockMethodCallHandler(
MethodChannel(channel.name, channel.codec),
(MethodCall call) async => switch (call.method) {
'listen' => handler.onListen(call.arguments, MockStreamHandlerEventSink(controller.sink)),
'cancel' => handler.onCancel(call.arguments),
_ => throw UnimplementedError('Method ${call.method} not implemented'),
},
);
final StreamSubscription<Object?> sub = controller.stream.listen(
(Object? e) => handlePlatformMessage(
channel.name,
channel.codec.encodeSuccessEnvelope(e),
null,
),
);
addTearDown(sub.cancel);
sub.onError((Object? e) {
if (e is! PlatformException) {
throw ArgumentError('Stream error must be a PlatformException');
}
handlePlatformMessage(
channel.name,
channel.codec.encodeErrorEnvelope(
code: e.code,
message: e.message,
details: e.details,
),
null,
);
});
sub.onDone(() => handlePlatformMessage(channel.name, null, null));
}