🎃

flutter testでshare_plusのメソッドが呼ばれたことを確認

2021/10/10に公開

はじめに

flutter testでshare_plusのメソッドが呼ばれたことを確認する方法です。
flutter testでurl_launcherのメソッドが呼ばれたことを確認とほぼ同じ内容ですが、追加で設定しないといけない部分があったので記載します。

環境

  • flutter: 2.5.2
  • share_plus: 3.0.2
  • mockito: 5.0.16

コード

// Package imports:
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:share_plus/share_plus.dart';
import 'package:share_plus_platform_interface/method_channel/method_channel_share.dart';
import 'package:share_plus_platform_interface/share_plus_platform_interface.dart';

// Project imports:
import 'sample_test.mocks.dart';

class SampleViewModel {
  Future<void> share(String text, {String? subject}) async {
    await Share.share(text, subject: subject);
  }
}

class FakeMethodChannelShare extends Fake
    with MockPlatformInterfaceMixin
    implements MethodChannelShare {}

([FakeMethodChannelShare])
void main() {
  late MockFakeMethodChannelShare mockMethodChannelShare;

  setUp(() {
    Share.disableSharePlatformOverride = true;
    mockMethodChannelShare = MockFakeMethodChannelShare();
    SharePlatform.instance = mockMethodChannelShare;
  });

  test('share', () async {
    final viewModel = SampleViewModel();

    const text = 'Sample Text';
    const subject = 'Sample Subject';

    when(mockMethodChannelShare.share(text, subject: subject))
        .thenAnswer((_) async {});

    await viewModel.share(text, subject: subject);

    verify(mockMethodChannelShare.share(text, subject: subject));
  });
}

mockito

mockitoのmockやwhen, verifyについては、こちらを参照ください。
https://pub.dev/packages/mockito

SharePlatform.instance

Share.shareメソッドは、SharePlatform.instanceで取得したインスタンスのメソッドを実行しています。
そのため、それをmockに差し替えることでメソッドが呼ばれたことを確認できるようにしています。
https://github.com/fluttercommunity/plus_plugins/blob/main/packages/share_plus/share_plus/lib/share_plus.dart

FakeMethodChannelShare

SharePlatform.instanceに設定するインスタンスですが、UrlLauncherPlatformのままではPlatformInterface.verifyTokenでエラーとなるため使用できませんでした。
そのため、MockPlatformInterfaceMixinを使用したFakeクラスを作成し、そのmockを作成するようにしています。

https://github.com/fluttercommunity/plus_plugins/blob/main/packages/share_plus/share_plus_platform_interface/lib/share_plus_platform_interface.dart
https://github.com/flutter/plugins/blob/plugin_platform_interface-v2.0.2/packages/plugin_platform_interface/lib/plugin_platform_interface.dart

Share.disableSharePlatformOverride = true;

SharePlatform.instanceの取得は、以下のget _platformが使用されています。
ただ、このままでは動作している環境がLinux/Windows以外のときしかSharePlatform.instanceで指定したmockが使用できない状態でした。
そのため、Share.disableSharePlatformOverride = true;を設定し、Linux/Windowsでも動作するようにしています。
(自分の場合、ローカルのMacでは正常動作、CI(Linux)でエラーとなり気づきました)

  static SharePlatform get _platform {
    if (__platform == null) {
      if (!_disablePlatformOverride && !kIsWeb) {
        if (Platform.isLinux) {
          __platform = ShareLinux();
        } else if (Platform.isWindows) {
          __platform = ShareWindows();
        }
      }
      __platform ??= SharePlatform.instance;
    }
    return __platform!;
  }

(コードを引用)
https://github.com/fluttercommunity/plus_plugins/blob/main/packages/share_plus/share_plus/lib/share_plus.dart#L30-L42

まとめ

share_plusのメソッドが呼ばれたことを確認することができました。
もっと簡単は方法などあれば、教えて下さい。

Discussion