自定义小部件的 Flutter 小部件测试失败
Posted
技术标签:
【中文标题】自定义小部件的 Flutter 小部件测试失败【英文标题】:Flutter widget test of a custom widget fails 【发布时间】:2019-05-23 01:30:53 【问题描述】:我正在尝试测试自定义小部件GoogleSignInButton
。
这里是小部件的实现:
import 'package:flutter/material.dart';
class GoogleSignInButton extends StatelessWidget
GoogleSignInButton(this.onPressed);
final Function onPressed;
@override
Widget build(BuildContext context)
Image _buildLogo()
return Image.asset(
"assets/g-logo.png",
height: 18.0,
width: 18.0,
);
Opacity _buildText()
return Opacity(
opacity: 0.54,
child: Text(
"Sign in with Google",
style: TextStyle(
fontFamily: 'Roboto-Medium',
color: Colors.black,
),
),
);
return MaterialButton(
height: 40.0,
onPressed: this.onPressed,
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_buildLogo(),
SizedBox(width: 24.0),
_buildText(),
],
),
);
我正在尝试通过下面的测试来测试onPressed
函数回调。
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../lib/ui/widgets/google_sign_in_button.dart';
void main()
testWidgets('my first widget test', (WidgetTester tester) async
var pressed = false;
var widget = GoogleSignInButton(
onPressed: () => ()
pressed = true;
,
);
await tester.pumpWidget(
StatefulBuilder(
builder: (BuildContext context, StateSetter setState)
return MaterialApp(
home: Material(
child: Center(
child: widget,
),
),
);
,
),
);
await tester.press(find.byWidget(widget));
expect(pressed, equals(true));
);
很遗憾,测试失败了。
我正在通过 flutter test test/widget_test.dart 在命令行上执行我的小部件测试,这是测试的结果:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected: <true>
Actual: <false>
When the exception was thrown, this was the stack:
#4 main.<anonymous closure> (file:///home/hans/Development/flutter/recipes_app/test/widget_test.dart:30:5)
<asynchronous suspension>
#5 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:72:23)
#6 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:566:19)
<asynchronous suspension>
#9 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:550:14)
#10 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:893:24)
#16 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:890:15)
#17 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:71:22)
#18 Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:27)
<asynchronous suspension>
#19 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:249:15)
<asynchronous suspension>
#24 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:246:5)
#25 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:166:33)
#30 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:165:13)
<asynchronous suspension>
#31 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:399:25)
<asynchronous suspension>
#45 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
#46 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
#47 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
(elided 28 frames from class _FakeAsync, package dart:async, and package stack_trace)
This was caught by the test expectation on the following line:
file:///home/hans/Development/flutter/recipes_app/test/widget_test.dart line 30
The test description was:
my first widget test
════════════════════════════════════════════════════════════════════════════════════════════════════
00:01 +0 -1: my first widget test [E]
Test failed. See exception logs above.
The test description was: my first widget test
00:02 +0 -1: Some tests failed.
任何想法为什么测试失败?
【问题讨论】:
【参考方案1】:你的关闭是错误的:
() => ()
pressed = true;
,
你需要这样写
()
pressed = true;
,
或者这样
() => ( pressed = true )
你需要触发tester.tap
方法。
这是我的工作代码:
var pressed = false;
var widget = GoogleSignInButton(
onPressed: ()
pressed = true;
debugPrint("Pressed!");
,
);
await tester.pumpWidget(
StatefulBuilder(
builder: (BuildContext context, StateSetter setState)
return MaterialApp(
home: Material(
child: Center(
child: widget,
),
),
);
,
),
);
expect(find.byWidget(widget), findsOneWidget);
await tester.tap(find.byWidget(widget));
expect(pressed, isTrue);
我假设当您运行项目时,您的 Widget 渲染良好并且不会抛出任何错误。
提示:在您的 test_file.dart
更改发生任何更改后创建一个 flutter clean
。
【讨论】:
以上是关于自定义小部件的 Flutter 小部件测试失败的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 测试中查找 CustomScrollView 内的小部件
在 Flutter 中编写自定义小部件(第1部分)ー EllipsizedText