Skip to content

Commit e5c19fb

Browse files
authored
Create mock-platform-channels.md (#5322)
* Create mock-platform-channels.md * Update mock-platform-channels.md * Update index.md * Update mock-platform-channels.md * Update mock-platform-channels.md
1 parent 1840d4a commit e5c19fb

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

src/docs/release/breaking-changes/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The following breaking changes have been reverted.
4949
* [SnackBars managed by the ScaffoldMessenger][]
5050
* [TextSelectionTheme migration][]
5151
* [Use maxLengthEnforcement instead of maxLengthEnforced][]
52+
* [Transition of platform channel test interfaces to flutter_test package][]
5253

5354
[Added BuildContext parameter to TextEditingController.buildTextSpan]: /docs/release/breaking-changes/buildtextspan-buildcontext
5455
[Android ActivityControlSurface attachToActivity signature change]: /docs/release/breaking-changes/android-activity-control-surface-attach
@@ -61,6 +62,7 @@ The following breaking changes have been reverted.
6162
[SnackBars managed by the ScaffoldMessenger]: /docs/release/breaking-changes/scaffold-messenger
6263
[TextSelectionTheme migration]: /docs/release/breaking-changes/text-selection-theme
6364
[Use maxLengthEnforcement instead of maxLengthEnforced]: /docs/release/breaking-changes/use-maxLengthEnforcement-instead-of-maxLengthEnforced
65+
[Transition of platform channel test interfaces to flutter_test package]: /docs/release/breaking-changes/mock-platform-channels
6466

6567
### Released in Flutter 1.22
6668

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: Transition of platform channel test interfaces to flutter_test package
3+
description: The setMockMessageHandler method related APIs have moved from package:flutter to package:flutter_test
4+
---
5+
6+
## Summary
7+
8+
The following methods have been replaced by APIs in the `flutter_test` package: `BinaryMessenger.checkMessageHandler`, `BinaryMessenger.setMockMessageHandler`, `BinaryMessenger.checkMockMessageHandler`, `BasicMessageChannel.setMockMessageHandler`, `MethodChannel.checkMethodCallHandler`, `MethodChannel.setMockMethodCallHandler`, and `MethodChannel.checkMockMethodCallHandler`. The `onPlatformMessage` callback is no longer used by the Flutter framework.
9+
10+
## Context
11+
12+
As part of a refactoring of the low-level plugin communications architecture, we have moved from the previous `onPlatformMessage`/`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 `ChannelBuffers` API.
13+
14+
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.
15+
16+
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 `flutter_test` package.
17+
18+
## Description of change
19+
20+
Specifically, the following APIs were affected:
21+
22+
* `BinaryMessenger.checkMessageHandler`: Obsolete.
23+
* `BinaryMessenger.setMockMessageHandler`: Replaced by `TestDefaultBinaryMessenger.setMockMessageHandler`.
24+
* `BinaryMessenger.checkMockMessageHandler`: Replaced by `TestDefaultBinaryMessenger.checkMockMessageHandler`.
25+
* `BasicMessageChannel.setMockMessageHandler`: Replaced by `TestDefaultBinaryMessenger.setMockDecodedMessageHandler`.
26+
* `MethodChannel.checkMethodCallHandler`: Obsolete.
27+
* `MethodChannel.setMockMethodCallHandler`: Replaced by `TestDefaultBinaryMessenger.setMockMethodCallHandler`.
28+
* `MethodChannel.checkMockMethodCallHandler`: Replaced by `TestDefaultBinaryMessenger.checkMockMessageHandler`.
29+
30+
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.
31+
32+
Tests using `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.)
33+
34+
Code that needs migrating may see errors such as the following:
35+
36+
```
37+
error - The method 'setMockMessageHandler' isn't defined for the type 'BinaryMessenger' at test/sensors_test.dart:64:8 - (undefined_method)
38+
39+
error • The method 'setMockMethodCallHandler' isn't defined for the type 'MethodChannel' • test/widgets/editable_text_test.dart:5623:30 • undefined_method
40+
41+
[error] The method 'setMockMessageHandler' isn't defined for the type 'BasicMessageChannel' (test/material/feedback_test.dart:37:36)
42+
```
43+
44+
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.
45+
46+
## Migration guide
47+
48+
The `flutter_test` package provides some shims so that uses of the obsolete `setMock...` and `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.
49+
50+
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 `WidgetTester` instance):
51+
52+
<!-- skip -->
53+
```dart
54+
// old code
55+
ServicesBinding.defaultBinaryMessenger.setMockMessageHandler(...);
56+
ServicesBinding.defaultBinaryMessenger.checkMockMessageHandler(...);
57+
// new code
58+
tester.binding.defaultBinaryMessenger.setMockMessageHandler(...);
59+
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(...);
60+
```
61+
62+
<!-- skip -->
63+
```dart
64+
// old code
65+
myChannel.setMockMessageHandler(...);
66+
myChannel.checkMockMessageHandler(...);
67+
// new code
68+
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler(myChannel, ...);
69+
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myChannel, ...);
70+
```
71+
72+
<!-- skip -->
73+
```dart
74+
// old code
75+
myMethodChannel.setMockMethodCallHandler(...);
76+
myMethodChannel.checkMockMethodCallHandler(...);
77+
// new code
78+
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(myMethodChannel, ...);
79+
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myMethodChannel, ...);
80+
```
81+
82+
Tests that use `package:test` and `test()` can be changed to use `package:flutter_test` and `testWidgets()` to get access to a `WidgetTester`.
83+
84+
Code that does not have access to a `WidgetTester` can refer to `TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger` instead of `tester.binding.defaultBinaryMessenger`.
85+
86+
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.
87+
88+
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.
89+
90+
## Timeline
91+
92+
Landed in version: 2.3.0-17.0.pre.1<br>
93+
In stable release: not yet
94+
95+
## References
96+
97+
{% include master-api.md %}
98+
99+
API documentation:
100+
* [`TestDefaultBinaryMessenger`][]
101+
* [`TestDefaultBinaryMessengerBinding`][]
102+
103+
Relevant PRs:
104+
* [PR #76288: Migrate to ChannelBuffers.push][]
105+
106+
<!-- Master channel link: -->
107+
[`TestDefaultBinaryMessenger`]: https://master-api.flutter.dev/flutter/[link_to_relevant_page].html
108+
[`TestDefaultBinaryMessengerBinding`]: https://master-api.flutter.dev/flutter/[link_to_relevant_page].html
109+
110+
[PR #76288: Migrate to ChannelBuffers.push]: {{site.github}}/flutter/flutter/pull/76288]

0 commit comments

Comments
 (0)