ChangeNotifier で更新される値の検証
ChangeNotifier を使用した場合に、値の更新を待って検証したいとき
以下のような class で値を検証したいとします。
class ProfileViewModel extends ChangeNotifier {
ProfileViewModel(this._updateProfileBodyUseCase);
final UpdateProfileBodyUseCase _updateProfileBodyUseCase;
String _body = '';
String get body => _body;
void onBodyEdited(String body) {
_updateProfileBodyUseCase.execute(body: body).then((value) {
_body = value;
notifyListeners();
});
}
}
class UpdateProfileBodyUseCase {
Future<String> execute({required String body}) { ... }
}
onBodyEditedFuture であれば待って検証することができますが、この場合、#execute からFuture.value を返してもそれより先に検証されてしまうため、待たなければ test が通りません。

Recipe

これは私の知る限りでは決まった方法があるわけではないため、Completer での対処を一例として記載しておきます。
test('test', () async {
when(updateProfileBodyUseCase.execute(body: anyNamed('body')))
.thenAnswer((_) => Future.value('body'));
final completer = Completer<void>();
viewModel.addListener(completer.complete);
viewModel.onBodyEdited('body');
await completer.future;
expect(viewModel.body, 'body');
});

Result

@GenerateMocks([
UpdateProfileBodyUseCase,
])
void main() {
late MockUpdateProfileBodyUseCase updateProfileBodyUseCase;
late ProfileViewModel viewModel;
setUp(() {
updateProfileBodyUseCase = MockUpdateProfileBodyUseCase();
viewModel = ProfileViewModel(updateProfileBodyUseCase);
});
test('test', () async {
when(updateProfileBodyUseCase.execute(body: anyNamed('body')))
.thenAnswer((_) => Future.value('body'));
final completer = Completer<void>();
viewModel.addListener(completer.complete);
viewModel.onBodyEdited('body');
await completer.future;
expect(viewModel.body, 'body');
});
}
リンクのコピー