Невозможно протестировать виджет, так как он неправильно создает свои зависимые виджеты
Я только начал работать с Flutter. Я следил за примером кода для реализации Flutter WebViews: https://pub.dev/packages/webview_flutter
Я немного изменил код, чтобы отключить кнопки навигации, когда это возможно. Однако теперь это делает невозможным кодирование. Вот мой код:
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();
}),
],
);
});
}
}
Проблема в том, что контроллер в NavigationControls имеет значение null при вызове await controller.canGoBack()
Есть ли способ поиздеваться над этим? Как видите, это не проходит через конструктор, поэтому я не знаю, как предоставить экземпляр 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);
});
}