How can I mock/stub out a Flutter platform channel/plugin?
android, dart, flutter, ios, unit-testing
Solution
You can use setMockMethodCallHandler to register a mock handler for the underlying method channel:
https://docs.flutter.io/flutter/services/MethodChannel/setMockMethodCallHandler.html
final List<MethodCall> log = <MethodCall>[];
MethodChannel channel = const MethodChannel('plugins.flutter.io/url_launcher');
// Register the mock handler.
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (message) {
log.add(methodCall);
});
await launch("http://example.com/");
expect(log, equals(<MethodCall>[new MethodCall('launch', "http://example.com/")]));
// Unregister the mock handler.
channel.setMockMethodCallHandler(null);
Problem
I read the introduction to platform-specific plugins/channels on the Flutter website and I browsed some simple examples of a plugin, like `url_launcher`: ``` // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'package:flutter/services.dart'; const _channel = const MethodChannel('plugins.flutter.io/url_launcher'); /// Parses the specified URL string and delegates handling of it to the /// underlying platform. /// /// The returned future completes with a [PlatformException] on invalid URLs and /// schemes which cannot be handled, that is when [canLaunch] would complete /// with false. Future<Null> launch(String urlString) { return _channel.invokeMethod( 'launch', urlString, ); } ``` In widgets tests or integration tests, how can I mock out or stub channels so I don't have to rely on the real device (running Android or iOS) say, actually launching a URL?