How To Mock Method Channels In Flutter.

Manav Garg @sigmapie8
2 min readSep 6, 2023

While testing apps, we sometimes run into situations where the logic being tested requires us to access third party plugins. That calls for mocking the plugin. Here’s how:

In this situation I have a bloc with an event CopyResult which copies text to device’s clipboard and calls a toast with the help of a third party plugin called FlutterToast.

on<CopyResult>(
(event, emit) async {
final string = event.result;
await Clipboard.setData(ClipboardData(text: string));
Fluttertoast.showToast(
msg: "Text Copied.",
toastLength: Toast.LENGTH_SHORT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black,
webBgColor: "black",
textColor: Colors.white,
fontSize: 16.0);

emit(UrlEncoderDecoderResult(result: string));
},
);

Initially, I was testing it like this:

blocTest("onCopyResult the String is copied to clipboard",
build: () => UrlEncoderDecoderBloc(),
act: (bloc) => bloc
.add(const CopyResult("http://example.org/api?foo=some message")),
wait: const Duration(seconds: 1),
expect: () => const [
UrlEncoderDecoderResult(
result: "http://example.org/api?foo=some message")
]);

Which led me to an error: MissingPluginException(No implementation found for method showToast on channel PonnamKarthik/fluttertoast)

This meant, my bloc was unable to find an implementation for fluttertoast. I used the method `setMockMethodCallHandler` to register a mock handler to handle my request:

blocTest("onCopyResult the String is copied to clipboard",
build: () {
MethodChannel channel =
const MethodChannel('PonnamKarthik/fluttertoast');

TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (message) {
// use this space to handle different type of method calls
// for the method channel, differently.
// Since I have no use of any return value, I'm returning null.
return null;
});

return UrlEncoderDecoderBloc();
},
act: (bloc) => bloc
.add(const CopyResult("http://example.org/api?foo=some message")),
wait: const Duration(seconds: 1),
expect: () => const [
UrlEncoderDecoderResult(
result: "http://example.org/api?foo=some message")
]);

More can be found in this wonderful answer by Adam Barth.

--

--