我刚刚开始与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);
});
}