自定义小部件的 Flutter 小部件测试失败

Flutter widget test of a custom widget fails

我正在尝试测试自定义小部件 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.

知道测试失败的原因吗?

你的关闭是错误的:

() => () {
    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