无法测试窗口小部件,因为它没有正确创建其依赖的窗口小部件

时间:2020-07-01 15:17:47

标签: flutter dart widget-test-flutter mockito-dart

我刚刚开始与Flutter合作。我一直在遵循用于实现Flutter WebViews的示例代码:https://pub.dev/packages/webview_flutter#-example-tab-

我对代码进行了些微更改,以在适用时禁用导航按钮。但是,这现在使得不可能进行编码。这是我的代码:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          primarySwatch: Colors.green, primaryColor: Colors.green[900]),
      home: Scaffold(
        appBar: AppBar(
          actions: <Widget>[NavigationControls(_controller.future)],
        ),
        body: Builder(builder: (BuildContext context) {
          return WebView(
              initialUrl: 'https://flutter.com',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController webViewController) {
                _controller.complete(webViewController);
              },
              gestureNavigationEnabled: true);
        }),
      ),
    );
  }
}

class NavigationControls extends StatefulWidget {
  const NavigationControls(this._webViewControllerFuture)
      : assert(_webViewControllerFuture != null);

  final Future<WebViewController> _webViewControllerFuture;

  _NavigationControlsState createState() => _NavigationControlsState();
}

class _NavigationControlsState extends State<NavigationControls> {
  bool _isBackButtonDisabled;
  bool _isForwardButtonDisabled;

  @override
  void initState() {
    super.initState();
    _isBackButtonDisabled = true;
    _isForwardButtonDisabled = true;
  }

  canGoBack(WebViewController controller) async {
    await controller.canGoBack()
        ? setState(() => _isBackButtonDisabled = false)
        : setState(() => _isBackButtonDisabled = true);
  }

  canGoForward(WebViewController controller) async {
    await controller.canGoForward()
        ? setState(() => _isForwardButtonDisabled = false)
        : setState(() => _isForwardButtonDisabled = true);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
        future: widget._webViewControllerFuture,
        builder:
            (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
          final bool webViewReady =
              snapshot.connectionState == ConnectionState.done;

          final WebViewController controller = snapshot.data;

          canGoBack(controller);
          canGoForward(controller);

          return Row(
            children: <Widget>[
              IconButton(
                  icon: const Icon(Icons.arrow_back_ios),
                  onPressed: (!webViewReady || _isBackButtonDisabled)
                      ? null
                      : () async {
                          await controller.goBack();
                        }),
              IconButton(
                  icon: const Icon(Icons.arrow_forward_ios),
                  onPressed: !webViewReady || _isForwardButtonDisabled
                      ? null
                      : () async {
                          await controller.goForward();
                        }),
            ],
          );
        });
  }
}

问题是调用await controller.canGoBack()时NavigationControls中的控制器为null

有什么办法嘲笑这个吗?如您所见,这没有通过构造函数传递,所以我不知道如何在测试中提供Mocked实例。这是我的测试尝试:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import 'package:myapp/main.dart';
import 'package:webview_flutter/webview_flutter.dart';

class MockWebViewController extends Mock implements WebViewController {}

void main() {
  testWidgets('Test Widget found', (WidgetTester tester) async {
    final webViewController = MockWebViewController();

    await tester.pumpWidget(MyApp());

    when(webViewController.canGoBack()).thenAnswer((_) async => true);
    when(webViewController.canGoForward()).thenAnswer((_) async => true);

    expect(find.byType(WebView), findsOneWidget);
  });
}

0 个答案:

没有答案