Flutter 单元测试 - 如何测试对字段的访问是否会抛出 LateInitializationError
Flutter unit test - How to test that an access to a field throws a LateInitializationError
我想测试一个 class 延迟字段尚未初始化的地方。
这是我的测试代码:
test('Set lang method', () {
// Throws an exception because the field osLang is not supposed to be initialized yet.
expect(() => dbRepository.osLang, throwsException);
dbRepository.setOsLang('fr');
expect(dbRepository.osLang, 'fr');
});
不幸的是,当我 运行 我的测试时出现这个错误:
package:test_api expect
package:flutter_test/src/widget_tester.dart 455:16 expect
test/src/models/repositories/db_repository_test.dart 20:7 main.<fn>.<fn>
Expected: throws <Instance of 'Exception'>
Actual: <Closure: () => String>
Which: threw LateError:<LateInitializationError: Field '_osLang@19447861' has not been initialized.>
stack package:my_app/src/models/repositories/db_repository.dart DBRepository._osLang
package:my_app/src/models/repositories/db_repository.dart 18:24 DBRepository.osLang
test/src/models/repositories/db_repository_test.dart 20:33 main.<fn>.<fn>.<fn>
package:test_api expect
package:flutter_test/src/widget_tester.dart 455:16 expect
test/src/models/repositories/db_repository_test.dart 20:7 main.<fn>.<fn>
which is not an instance of 'Exception'
我尝试将 throwsException
更改为 throwsA(isA<LateInitializationError>)
,但我的 IDE 没有找到任何名为 LateInitializationError
的 class。
我在 flutter 文档中找不到解决该问题的方法,所以我在这里问一下。感谢您的回答。
Error
不是 Exception
,所以 throwsException
不会匹配它。
LateInitializationError
曾经是public类型,现在好像不是public了。你可以求助于 throwsA(isA<Error>())
。 (基于 last available public documentation for it,它直接派生自 Error
,因此没有更具体的类型可以测试。)您可以检查 Error
字符串以使其更具体:
expect(
() => dbRepository.osLang,
throwsA(
predicate<Error>(
(error) => error.toString().contains('LateInitializationError'),
),
),
);
综上所述,在我看来,LateInitializationError
的测试无论如何都可能有点问题。理想情况下 late
变量不应作为 API 的一部分公开。如果您的代码需要显式初始化步骤,那么使用描述性错误消息进行显式检查会更清楚。也就是说,而不是:
late final String someProperty;
你可以有这样的东西:
String? _someProperty;
String get someProperty {
var _someProperty = this._someProperty;
if (_someProperty == null) {
throw StateError('init() must be called first');
}
return _someProperty;
}
我想测试一个 class 延迟字段尚未初始化的地方。
这是我的测试代码:
test('Set lang method', () {
// Throws an exception because the field osLang is not supposed to be initialized yet.
expect(() => dbRepository.osLang, throwsException);
dbRepository.setOsLang('fr');
expect(dbRepository.osLang, 'fr');
});
不幸的是,当我 运行 我的测试时出现这个错误:
package:test_api expect
package:flutter_test/src/widget_tester.dart 455:16 expect
test/src/models/repositories/db_repository_test.dart 20:7 main.<fn>.<fn>
Expected: throws <Instance of 'Exception'>
Actual: <Closure: () => String>
Which: threw LateError:<LateInitializationError: Field '_osLang@19447861' has not been initialized.>
stack package:my_app/src/models/repositories/db_repository.dart DBRepository._osLang
package:my_app/src/models/repositories/db_repository.dart 18:24 DBRepository.osLang
test/src/models/repositories/db_repository_test.dart 20:33 main.<fn>.<fn>.<fn>
package:test_api expect
package:flutter_test/src/widget_tester.dart 455:16 expect
test/src/models/repositories/db_repository_test.dart 20:7 main.<fn>.<fn>
which is not an instance of 'Exception'
我尝试将 throwsException
更改为 throwsA(isA<LateInitializationError>)
,但我的 IDE 没有找到任何名为 LateInitializationError
的 class。
我在 flutter 文档中找不到解决该问题的方法,所以我在这里问一下。感谢您的回答。
Error
不是 Exception
,所以 throwsException
不会匹配它。
LateInitializationError
曾经是public类型,现在好像不是public了。你可以求助于 throwsA(isA<Error>())
。 (基于 last available public documentation for it,它直接派生自 Error
,因此没有更具体的类型可以测试。)您可以检查 Error
字符串以使其更具体:
expect(
() => dbRepository.osLang,
throwsA(
predicate<Error>(
(error) => error.toString().contains('LateInitializationError'),
),
),
);
综上所述,在我看来,LateInitializationError
的测试无论如何都可能有点问题。理想情况下 late
变量不应作为 API 的一部分公开。如果您的代码需要显式初始化步骤,那么使用描述性错误消息进行显式检查会更清楚。也就是说,而不是:
late final String someProperty;
你可以有这样的东西:
String? _someProperty;
String get someProperty {
var _someProperty = this._someProperty;
if (_someProperty == null) {
throw StateError('init() must be called first');
}
return _someProperty;
}