FlutterのTestでCallbackをモックする

Photo by Angèle Kamp / Unsplash

FlutterのTestでCallbackをmockitoでモックする

FlutterのテストでChangeNotifierのサブクラスのaddListenerに渡したCallbackが呼ばれたかテストしたい場合に、ダミーのコールバックでフラグを立ててフラグをexpectで検査することがある。

これをmockitoを使ってverifyで検証する方法がある。

返値がVoidのモック

まず以下のmixin(もしくはclassでも可)を作成する。

mixin Callback<T> {
  T call();
}

callメソッドを持ったクラスは関数のようにcallメソッドを呼ぶことができるようになる。例えば以下のように。

class A {
  void call() { print('a'); }
}

final a = A();
a();  // a.call()が実行されaが出力される

次にmockitoのGenerateMocksアノテーションで、CallbackからCallbackのモックを作成する。以下を記述してbuild_runner buildを実行するとモックが定義されたファイルが生成される。

@GenerateMocks([], customMocks: [
  MockSpec<Callback<void>>(as: #MockVoidCallback)
])

作成したモックをテストで利用する。

class MyClass extends ChangeNotifier {
  void a() {
    notifyListeners();
  }
}

@GenerateMocks([], customMocks: [
  MockSpec<Callback<void>>(as: #MockVoidCallback)
])
void main() {
  final myClass = MyClass();

  test('VoidCallback', () {
    final callback = MockVoidCallback();
    myClass.addListener(callback);
    myClass.a();
    verify(callback.call()).called(1);
  });
}

aメソッドを実行するとnotifyListenersメソッドの実行によりmyClass.addListenerに渡したコールバックが実行されることを検証している。

myClass.addListenerにMockVoidCallbackのインスタンスを渡している。notifyListenersによりcallback.call()が実行される。

verifyでcallback.call()が1回実行されたことが確認される。

返値がvoidでない場合のモック

前の例はvoid Function()のモックだった。ここでは返値がvoidではないコールバックのモックを作成する。

以下のように記述するとStringを返す関数のモックを作成できる。

@GenerateMocks([], customMocks: [
  MockSpec<Callback<String>>(as: #MockStringCallback)
])

テストではwhen関数で返値の値を設定して利用する。

class MyClass {
  void b(String Function() callback) {
    callback();
  }
}

@GenerateMocks([], customMocks: [
  MockSpec<Callback<String>>(as: #MockStringCallback)
])
void main() {
  final myClass = MyClass();

  test('StringCallback', () {
    final callback = MockStringCallback();
    when(callback.call()).thenReturn('');
    myClass.b(callback);
    verify(callback.call()).called(1);
  });
}
Ryoichi Izumita

Ryoichi Izumita