如何在Flutter测试中模拟'google_maps_flutter'包?

7

我最近开始涉足Flutter,但就在我准备写一些小部件测试时,发现我不太确定如何模拟Google Maps Flutter包。

许多示例都包括使用库“mockito”来模拟类,但这假定Google Maps小部件将被注入到要测试的小部件中。不幸的是,在给定的文档和启动指南中,似乎很难实现这一点:

class MapsDemo extends StatefulWidget {
  @override
  State createState() => MapsDemoState();
}

class MapsDemoState extends State<MapsDemo> {

  GoogleMapController mapController;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(15.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Center(
            child: SizedBox(
              width: 300.0,
              height: 200.0,
              child: GoogleMap(
                onMapCreated: _onMapCreated,
              ),
            ),
          ),
          RaisedButton(
            child: const Text('Go to London'),
            onPressed: mapController == null ? null : () {
              mapController.animateCamera(CameraUpdate.newCameraPosition(
                const CameraPosition(
                  bearing: 270.0,
                  target: LatLng(51.5160895, -0.1294527),
                  tilt: 30.0,
                  zoom: 17.0,
                ),
              ));
            },
          ),
        ],
      ),
    );
  }

  void _onMapCreated(GoogleMapController controller) {
    setState(() { mapController = controller; });
  }
}

请注意,不能传入GoogleMaps小部件,因为onMapCreated是必需的函数,而该函数依赖于私有类方法(使父小部件访问GoogleMapsController)。许多其他mockito模拟函数没有这种回调函数来设置状态。
我没有看到任何其他可以有效模拟GoogleMaps小部件的软件包,所以我没有任何示例可供参考。理想情况下,我期望像node.s中的proxyquire或sinon一样的行为(您不需要将模拟库传递到function.constructors中),但看起来,需要将mockified类传递到被测试的小部件中。
有没有其他想法可以模拟此库进行测试?还是我应该接受测试实际功能的事实?

1
你解决了这个问题吗?我遇到了相同的问题,模拟“GoogleMaps”。 - Alejandro Viquez
1个回答

2
我成功地通过模拟GoogleMaps使用的通道来模拟它。
setUpAll(() async {
  SystemChannels.platform_views.setMockMethodCallHandler((MethodCall call) {
    switch (call.method) {
      case 'create':
        return Future<int>.sync(() => 1);
      default:
        return Future<void>.sync(() {});
    }
  });

  MethodChannel('plugins.flutter.io/google_maps_0', StandardMethodCodec())
    .setMockMethodCallHandler((MethodCall methodCall) async {
      return null;
    });
}

我从这个webview插件test (类似于GoogleMaps小部件的PlatformView)和这个GoogleMaps插件test中获得了灵感。


1
非常感谢让我走上正确的轨道!注意:如果您使用控制器的任何方法,例如 getLatLong,则需要在上面的第二个模拟处理程序中实现模拟。此外,如果您在一个文件中有多个测试,则地图的ID会增加,因此您需要模拟 'plugins.flutter.io/google_maps_1''plugins.flutter.io/google_maps_2'等等。 - FreewheelNat
很高兴能帮到你。确实,你使用的方法越多,需要编写的样板代码就越多。 - ncuillery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接