Как мне заглушить обратные вызовы метода?

Я использую Firebase Phone Auth в своем проекте Flutter и хочу протестировать свой класс аутентификации. Я знаю как использовать when() а также .thenAnswer() из Мокито с типичными Futureс.

FirebaseAuth обрабатывает ответы с помощью обратных вызовов.

      await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

В частности, мне нужно заглушить verificationFailed а также verificationCompleted обратные вызовы, но я понятия не имею, как мне это сделать, поскольку документы Mockito ничего не говорят об обратных вызовах.

1 ответ

Решение

На самом деле вы не спрашиваете, как заглушить сами обратные вызовы; вы спрашиваете, как вызывать обратные вызовы для заглушенного метода. Вы бы использовали захваченные аргументы обратного вызова так же, как любые другие захваченные аргументы:

      // Sample class with a method that takes a callback.
abstract class Foo {
  void f(String Function(int x) callback, int y);
}

@GenerateMocks([Foo])
void main() {
  var mockFoo = MockFoo();
  mockFoo.f((x) => '$x', 42);
  var captured = verify(mockFoo.f(captureAny, any)).captured;
  var f = captured[0] as String Function(int);
  print(f(88)); // Prints: 88
}

В вашем случае, я думаю, это будет примерно так:

          test('cant verify phonenumber', () async {
      await authCodeViewModel.getSmsCodeWithFirebase();
      var captured = verify(mockFirebaseAuth.verifyPhoneNumber(
              phoneNumber: any,
              codeSent: anyNamed('codeSent'),
              verificationCompleted: anyNamed('verificationCompleted'),
              verificationFailed: captureNamed('verificationFailed'),
              codeAutoRetrievalTimeout: anyNamed('codeAutoRetrievalTimeout')))
          .captured;
      var verificationFailed = captured[0] as PhoneVerificationFailed;
      verificationFailed(FirebaseAuthException());
      expect(authCodeViewModel.initModelState, DataState.error);
    });

Конечно, если вы предоставляете обратные вызовы, вам в первую очередь не нужно их захватывать; вы можете просто вызвать их напрямую.

Другие вопросы по тегам