The following methods have been replaced by APIs in the
onPlatformMessage callback is no longer used by the Flutter framework.
As part of a refactoring of the low-level plugin communications architecture, we have moved from the previous
handlePlatformMessage logic to a per-channel buffering system implemented in the engine in the
ChannelBuffers class. To maintain compatibility with existing code, the existing
BinaryMessenger.setMessageHandler API has been refactored to use the new
One difference between the
ChannelBuffers API and the previous API is that the new API is more consistent in its approach to asynchrony. As a side-effect, the APIs around message passing are now entirely asynchronous.
This posed a problem for the implementation of the legacy testing APIs which, for historical reasons, were previously in the
flutter package. Since they relied on the underlying logic being partly synchronous, they required refactoring. To avoid adding even more test logic into the
flutter package, a decision was made to move this logic to the
Description of change
Specifically, the following APIs were affected:
BinaryMessenger.setMockMessageHandler: Replaced by
BinaryMessenger.checkMockMessageHandler: Replaced by
BasicMessageChannel.setMockMessageHandler: Replaced by
MethodChannel.setMockMethodCallHandler: Replaced by
MethodChannel.checkMockMethodCallHandler: Replaced by
These replacements are only available to code using the new
TestDefaultBinaryMessengerBinding (such as any code using
testWidgets in a
flutter_test test). There is no replacement for production code that was using these APIs, as they were not intended for production code use.
checkMessageHandler have no equivalent in the new API, since message handler registration is handled directly by the
ChannelBuffers object, which does not expose the currently registered listener for a channel. (Tests verifying handler registration appear to be rare.)
Code that needs migrating may see errors such as the following:
error - The method 'setMockMessageHandler' isn't defined for the type 'BinaryMessenger' at test/sensors_test.dart:64:8 - (undefined_method) error • The method 'setMockMethodCallHandler' isn't defined for the type 'MethodChannel' • test/widgets/editable_text_test.dart:5623:30 • undefined_method [error] The method 'setMockMessageHandler' isn't defined for the type 'BasicMessageChannel' (test/material/feedback_test.dart:37:36)
In addition, the
onPlatformMessage callback, which previously was hooked by the framework to receive messages from plugins, is no longer used (and will be removed in due course). As a result, calling this callback to inject messages into the framework no longer has an effect.
flutter_test package provides some shims so that uses of the obsolete
checkMock... methods will continue to work. Tests that previously did not import
package:flutter_test/flutter_test.dart can do so to enable these shims; this should be sufficient to migrate most code.
These shim APIs are deprecated, however. Instead, in code using
WidgetTester (e.g. using
testWidgets), it is recommended to use the following patterns to replace calls to those methods (where
tester is the
// old code ServicesBinding.defaultBinaryMessenger.setMockMessageHandler(...); ServicesBinding.defaultBinaryMessenger.checkMockMessageHandler(...); // new code tester.binding.defaultBinaryMessenger.setMockMessageHandler(...); tester.binding.defaultBinaryMessenger.checkMockMessageHandler(...);
// old code myChannel.setMockMessageHandler(...); myChannel.checkMockMessageHandler(...); // new code tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler(myChannel, ...); tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myChannel, ...);
// old code myMethodChannel.setMockMethodCallHandler(...); myMethodChannel.checkMockMethodCallHandler(...); // new code tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(myMethodChannel, ...); tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myMethodChannel, ...);
Tests that use
test() can be changed to use
testWidgets() to get access to a
Code that does not have access to a
WidgetTester can refer to
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger instead of
Tests that do not use the default test widgets binding (
AutomatedTestWidgetsFlutterBinding, which is initialized by
testWidgets) can mix the
TestDefaultBinaryMessengerBinding mixin into their binding to get the same results.
Tests that manipulate
onPlatformMessage will no longer function as designed. To send mock messages to the framework, consider using
ChannelBuffers.push. There is no mechanism to intercept messages from the plugins and forward them to the framework in the new API. If your use case requires such a mechanism, please file a bug.
Landed in version: 2.3.0-17.0.pre.1
In stable release: not yet