如何恢复FlutterError.onError?

Mea*_*Man 19 flutter flutter-test flutter-integration-test

在我的应用程序中,我将 flutter onError 记录到 crashalytics,

FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
Run Code Online (Sandbox Code Playgroud)

在运行集成测试时,如果发生一些异常,我会在控制台中收到以下语句,并且测试会挂起,

运行测试时引发以下异常:I/flutter (30479):测试覆盖了 FlutterError.onError 但未能将其返回到原始状态,或者出现了无法处理的意外其他错误。通常,这是由于在恢复 FlutterError.onError 之前使用了 Expect() 造成的。

控制台中的上述消息表明覆盖有问题onError,我如何FlutterError.onError根据控制台中出现的建议返回到其原始状态。

请注意,我正在使用新推荐的方式进行集成测试

Hie*_*ham 11

onError是 的公共静态成员FlutterError,因此从技术上讲,它可以被任何地方的任何人覆盖。在运行测试主体之前,函数本身也会使用自己的错误处理testWidgets()程序覆盖。FlutterError.onError您可以阅读其源代码以获取更多信息。

基本上,下面是发生的事情:

testWidgets('', (tester) async { // onError is overridden with the handler of the test framework
  await app.main(); // onError is overridden again with crashlytics error handler
  //...
  expect(); // Flutter yells that you should not have touched its onError
});
Run Code Online (Sandbox Code Playgroud)

关键是 Flutter 测试框架需要它onError才能正常工作。因此,无论您做什么,请记住调用测试框架的错误处理程序。

FlutterError.onError以下是我在项目中使用的“恢复” (并执行其他操作)的方法:

testWidgets('', (tester) async {
  final originalOnError = FlutterError.onError!;
  FlutterError.onError = (FlutterErrorDetails details) {
    // do something like ignoring an exception
    originalOnError(details); // call test framework's error handler
  };
  // ...
  expect();
});
Run Code Online (Sandbox Code Playgroud)

经过一些修改,我认为你的问题是可以解决的。


Har*_*dia 7

我编写的这个辅助函数对我有用:


Future<void> restoreFlutterError(Future<void> Function() call) async {
  final originalOnError = FlutterError.onError!;
  await call();
  final overriddenOnError = FlutterError.onError!;

  // restore FlutterError.onError
  FlutterError.onError = (FlutterErrorDetails details) {
    if (overriddenOnError != originalOnError) overriddenOnError(details);
    originalOnError(details);
  };
}

void main(){
  testWidgets("some test", (tester) async {
    await restoreFlutterError(() async {
      app.main();
      await tester.pumpAndSettle();
    });
    // ...
    expect(...);
  });
}
Run Code Online (Sandbox Code Playgroud)

任何覆盖的内容都FlutterError.onError可以被包装restoreFlutterError- 该函数确保调用两个onError处理程序(您的处理程序和测试框架设置的处理程序)。


Gui*_*lva 1

嗯,好吧..看来我们有几个与此相关的问题:link-1link-2link-3

长话短说:该integration_test库目前似乎只针对“快乐路径”进行了优化。

就我而言,Firebase 与integration_test启用此行时发生冲突:

   FirebaseMessaging.onBackgroundMessage(_onBackgroundOrTerminatedHandler);
Run Code Online (Sandbox Code Playgroud)

一旦我禁用它(运行集成测试时),错误就消失了。