Flutter中如何测试是否抛出异常?

Bry*_*der 4 dart flutter

我似乎无法测试Flutter中是否抛出异常。考虑到我期望出现异常,如果抛出异常,我希望测试能够通过。

我尝试过的:

import 'package:flutter_test/flutter_test.dart';

void main() {
  test('Range error test', () {
    expect(throw RangeError(""), throwsA(RangeError("")));
  });
  test('Range error test', () {
    expect(throw RangeError(""), throwsA(RangeError));
  });

  test('Range error test', () {
    expect(throw RangeError(""), throwsRangeError);
  });

  test('ConcurrentModificationError error test', () {
    expect(throw ConcurrentModificationError(""), throwsA(ConcurrentModificationError));
  });

  test('NumberFormat error test', () {
    expect(int.parse("sdffg"), throwsA(FormatException));
  });

  test('NumberFormat error test', () {
    expect(int.parse("sdffg"), throwsFormatException);
  });

  test('Range error test', () {
    var list = [];
    expect(list[1], throwsRangeError);
  });

  test('Range error test', () {
    var list = [];
    expect(list[1], throwsA(RangeError));
  });
}
Run Code Online (Sandbox Code Playgroud)

pubspec.yaml 中的依赖项:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter
  test:
Run Code Online (Sandbox Code Playgroud)

在 Android Studio 中运行它们后出现错误(从 cli 运行时出现相同的错误): 错误

Hug*_*sos 6

让我们举一个例子:

expect(throw RangeError(""), throwsA(RangeError("")));
Run Code Online (Sandbox Code Playgroud)

这里有一些问题。

由于throw RangeError("")它是较大表达式的一部分,因此它会在整个表达式之前进行评估,因此如果中断流程,您就不能指望对其expect()进行评估。throw RangeError("")

为了使这个解释更具说教性,假设我们将参数提取到变量中:

final neverAssigned = throw RangeError("");
final throwsRangeError = throwsA(RangeError(""));
expect(neverAssigned, throwsRangeError);
Run Code Online (Sandbox Code Playgroud)

您可能已经意识到,我们永远不会到达,expect()因为程序已经在第一行抛出了异常。

要解决这个问题,expect()需要您传递一个可能抛出异常的函数。它将检查它是否是一个函数,将调用包装在 try-catch 中,并检查抛出的错误是否是您所期望的。

我们最终应该得到这样的结果:

expect(() => throw RangeError(""), throwsA(RangeError("")));
Run Code Online (Sandbox Code Playgroud)

但是,这不太有效,因为错误通常不会实现operator ==hashCode,所以RangeError("") == RangeError("")给你false。这意味着检查抛出的错误是否正是您所期望的并不那么简单。

相反,您应该仅使用类似 的内容检查类型throwsA(isA<RangeError>()),或者使用 的内容检查消息having