I want to test a class where a late field is not yet initialized.
Here is the code of my test :
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');
});
Unfortunately, I get this error when I run my test:
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'
I tried to change the throwsException
with throwsA(isA<LateInitializationError>)
but my IDE doesn't find any class called LateInitializationError
.
I can't find a solution to that problem on the flutter documentation, so I'm asking it here. Thanks for your answers.
CodePudding user response:
Error
s aren't Exception
s, so throwsException
won't match it.
LateInitializationError
used to be a public type, but it seems that it isn't public anymore. You could resort to throwsA(isA<Error>())
. (Based on the last available public documentation for it, it derives directly from Error
, so there isn't a more specific type to test against.) You could check the Error
string to be more specific:
expect(
() => dbRepository.osLang,
throwsA(
predicate<Error>(
(error) => error.toString().contains('LateInitializationError'),
),
),
);
All that said, in my opinion, testing for LateInitializationError
might be a bit questionable anyway. Ideally late
variables shouldn't be exposed as part of your API. If your code requires an explicit initialization step, then it'd be clearer to have an explicit check with a descriptive error message. That is, instead of:
late final String someProperty;
you could have something like:
String? _someProperty;
String get someProperty {
var _someProperty = this._someProperty;
if (_someProperty == null) {
throw StateError('init() must be called first');
}
return _someProperty;
}
CodePudding user response:
why dont use null expression and check if its null better than late