Flutterプラグインのテストで正しくMethodCallが呼ばれてるかテストするには

Posted by kwmt27 on Sun, Mar 17, 2019

下記のコードは、flutter_inapp_purchaseのdartコードの1つのメソッドで、実装はわかりやすいように1つのinvokedMethodに修正したものですが、Flutterプラグインでネイティブのメソッドを呼び出すにはMethodChannelのinvokedMethod(文字列,パラメータ)のような感じで呼び出します。

static final MethodChannel _channel = const MethodChannel('flutter_inapp');
static Future<List<IAPItem>> getProducts(List<String> skus) async {
    dynamic result = await _channel.invokeMethod(
        'getItemsByType',
        <String, dynamic>{
        'type': 'inapp',
        'skus': skus,
        },
    );
    return extractItems(result);
}

invokedMethodは文字列を渡すので、例えば 'getItemsByType'が 極端ですが'get'とかになっていてもコンパイルできてしまいます。

そこで、getProductsが正しく'getItemsByType'が呼ばれている確認するには、下記のコードのようにisMethodCallを使います。

test('invokes correct method', () async {
  await FlutterInappPurchase.getProducts(skus);
  expect(log, <Matcher>[
    isMethodCall(
      'getItemsByType',
      arguments: <String, dynamic>{
        'type': 'inapp',
        'skus': skus,
      },
    ),
  ]);
});

このようにすると、たとえば先程の例のように'getItemsByType'getになっていた場合、テストを実行すると、期待する文字列は'getItemsByType'だけど実際はgetになっているよ、と教えてくれます。

Expected: [
            <has method name: 'getItemsByType' with arguments: {'type': 'inapp', 'skus': ['testsku']}>
          ]
  Actual: [MethodCall:MethodCall(get, {type: inapp, skus: [testsku]})]
   Which: does not match has method name: 'getItemsByType' with arguments: {'type': 'inapp', 'skus': ['testsku']} at location [0]


comments powered by Disqus