Flutter google map 如何在 GoogleMap 的小部件 onCreated 函数之外实例化 GoogleMapController 进行测试?

问题描述 投票:0回答:5

我正在使用插件google_maps_flutter 1.2.0,我想实例化一个GoogleMapController来测试一些块的事件,其中控制器的值不能为空。 不幸的是,我不知道该怎么做,因为据我所知,GoogleMapController 无法在 GoogleMap() Widget 的“OnCreated”函数之外实例化。

 GoogleMap(onMapCreated: (GoogleMapController controller) {
                         // Can only be instanciate here
                        },
          );

不可能做这样的事:

  GoogleMapController controller = new GoogleMapsController();

我只能这样做,并且控制器为空:

 GoogleMapController controller;

我尝试了多种方法,但没有任何效果,有人可以帮助我吗?

flutter google-maps testing
5个回答
1
投票

首先,

GoogleMapController _googleMapController
在你的
_WidgetState
中。
然后

GoogleMap(onMapCreated: (GoogleMapController controller) {
        _googleMapController = controller;
    }
);  

创建 Google 地图后,您可以在小部件中的任何位置使用 _googleMapController。


1
投票

你可以这样使用 - 在你的州:

final Completer<GoogleMapController> _controller =
      Completer<GoogleMapController>();

在你的 GoogleMap() 小部件中就像这样

 GoogleMap(
          myLocationButtonEnabled: false,
          zoomControlsEnabled: false,
          onMapCreated: (GoogleMapController controller) =>
              _googleMapController.complete(controller),
          initialCameraPosition: _initialCameraPosition),

0
投票

您可以在构建方法之前使用 use

_googleMapController? = controller;
,在您想要使用您的方法或您想要对实例执行的任何操作的地方制作一些 if 语句
(_googleMapController != null)


0
投票

如果您使用的是 Flutter 2.5.3 及更高版本,您可以在变量声明前面添加一个 Late ,即

late GoogleMapController _googleMapController;

在您的谷歌地图小部件中,您可以照常使用该变量

onMapCreated: (controller) => _googleMapController = controller,


0
投票

套餐:

  • flutter_bloc:^8.1.6
  • bdd_widget_test:^1.7.4
  • 模拟:^5.4.4
  • google_maps_flutter:^2.9.0
  • build_runner:^2.4.11

map_page.feature

Feature: Map

    Background:
        Given The app is initialized
        And The page is displayed

    @success
    Scenario: User is centered on their location
        When I tap {Icons.my_location} button to get my current location
        Then The map is centered on my location

di.dart

void setupLocator() {
    // Any other injections...

    sl.registerFactory<Completer<GoogleMapController>>(
        () => Completer<GoogleMapController>(),
    );
};

map_page.dart

class MapPage extends StatefulWidget {
  const MapPage({super.key});

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  final Completer<GoogleMapController> _controller =
      sl<Completer<GoogleMapController>>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocListener<MapBloc, MapState>(
        listener: _onGetLocation,
        child: GoogleMap(
          onMapCreated: (controller) => _controller.complete(controller),
          initialCameraPosition: const CameraPosition(
            target: LatLng(0, 0),
            zoom: 15,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.my_location),
        onPressed: () => context.read<MapBloc>().add(GetMyLocation()),
      ),
    );
  }

  void _onGetLocation(BuildContext context, MapState state) async {
    if (state is SuccessGetMyLocation) {
      var controller = await _controller.future;
      controller.animateCamera(CameraUpdate.newCameraPosition(
        CameraPosition(target: state.latLng, zoom: 15),
      ));
    }
  }
}

test_helper.dart

@GenerateNiceMocks(<MockSpec>[
  // Any other MockSpec...
  MockSpec<Completer<GoogleMapController>>(),
  MockSpec<GoogleMapController>(),
])
void main() {}

di_helper.dart

void setupDiHelper() {
    // Any other injections...

    sl.registerLazySingleton<Completer<GoogleMapController>>(
        () => MockCompleter(),
    );
};

the_app_is_initialized.dart

/// Usage: The app is initialized
Future<void> theAppIsInitialized(WidgetTester tester) async {
  PatrolTester $ = PatrolTester(
    tester: tester,
    config: const PatrolTesterConfig(),
  );
  await setupDiHelper();
  await $.pump();
}

the_page_is_displayed.dart

/// Usage: The page is displayed
Future<void> thePageIsDisplayed(WidgetTester $) async {
  await $.pumpWidget(
    MultiBlocProvider(
      providers: [
        BlocProvider<MapBloc>(
          create: (context) => sl<MapBloc>(),
        ),
      ],
      child: MaterialApp(
        home: const MapPage(),
      ),
    ),
  );
}

i_tap_button_to_get_my_current_location.dart

/// Usage: I tap {Icons.my_location} button to get my current location
Future<void> iTapButtonToGetMyCurrentLocation(
    WidgetTester $, IconData icon) async {
  var state = SuccessGetMyLocation(Position.fromMap(decode(Fixture.position)));
  when(sl<MapBloc>().state).thenReturn(state);

  // Create a mock GoogleMapController
  final mockController = MockGoogleMapController();

  // Stub the Completer's future to return the mock controller
  final completer = sl<Completer<GoogleMapController>>();
  when(completer.future).thenAnswer((_) async => mockController);

  // Stub the animateCamera method on the mock controller
  when(mockController.animateCamera(any)).thenAnswer((_) async => {});

  await $.tap(find.byIcon(icon));
  await $.pump();
}

the_map_is_centered_on_my_location.dart

/// Usage: The map is centered on my location
Future<void> theMapIsCenteredOnMyLocation(WidgetTester $) async {
  var controller = await sl<Completer<GoogleMapController>>().future;

  // Mock the position
  var position = Position.fromMap(decode(Fixture.position));
  var mockedLatLng = LatLng(position.latitude, position.longitude);
  var mockedScreenCoordinate = const ScreenCoordinate(x: 0, y: 0);

  // Add a stub for the getLatLng method
  when(controller.getLatLng(mockedScreenCoordinate))
      .thenAnswer((_) async => mockedLatLng);

  var latLng = await controller.getLatLng(mockedScreenCoordinate);

  expect(latLng, equals(mockedLatLng));
}

hooks.dart

abstract class Hooks {
  const Hooks._();

  static FutureOr<void> beforeEach(String title, [List<String>? tags]) {
    if (tags?.contains('success') ?? false) {
      provideDummy<MapState>(
        SuccessGetMyLocation(Position.fromMap(decode(Fixture.position))),
      );
    } else if (tags?.contains('failure') ?? false) {
    }
  }

  static FutureOr<void> beforeAll() {}

  static FutureOr<void> afterEach(
    String title,
    bool success, [
    List<String>? tags,
  ]) {}

  static FutureOr<void> afterAll() {}
}

map_page_test.dart

此文件是使用

map_page.feature
dart run build_runner build

自动生成的
© www.soinside.com 2019 - 2024. All rights reserved.