// Mocks generated by Mockito 5.1.0 from annotations
// in google_sign_in/test/google_sign_in_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i4;

import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'
    as _i3;
import 'package:google_sign_in_platform_interface/src/types.dart' as _i2;
import 'package:mockito/mockito.dart' as _i1;

// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types

class _FakeGoogleSignInTokenData_0 extends _i1.Fake
    implements _i2.GoogleSignInTokenData {}

/// A class which mocks [GoogleSignInPlatform].
///
/// See the documentation for Mockito's code generation for more information.
class MockGoogleSignInPlatform extends _i1.Mock
    implements _i3.GoogleSignInPlatform {
  MockGoogleSignInPlatform() {
    _i1.throwOnMissingStub(this);
  }

  @override
  bool get isMock =>
      (super.noSuchMethod(Invocation.getter(#isMock), returnValue: false)
          as bool);
  @override
  _i4.Future<void> init(
          {List<String>? scopes = const [],
          _i2.SignInOption? signInOption = _i2.SignInOption.standard,
          String? hostedDomain,
          String? clientId}) =>
      (super.noSuchMethod(
          Invocation.method(#init, [], {
            #scopes: scopes,
            #signInOption: signInOption,
            #hostedDomain: hostedDomain,
            #clientId: clientId
          }),
          returnValue: Future<void>.value(),
          returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
  @override
  _i4.Future<void> initWithParams(_i2.SignInInitParameters? params) =>
      (super.noSuchMethod(Invocation.method(#initWithParams, [params]),
          returnValue: Future<void>.value(),
          returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
  @override
  _i4.Future<_i2.GoogleSignInUserData?> signInSilently() =>
      (super.noSuchMethod(Invocation.method(#signInSilently, []),
              returnValue: Future<_i2.GoogleSignInUserData?>.value())
          as _i4.Future<_i2.GoogleSignInUserData?>);
  @override
  _i4.Future<_i2.GoogleSignInUserData?> signIn() =>
      (super.noSuchMethod(Invocation.method(#signIn, []),
              returnValue: Future<_i2.GoogleSignInUserData?>.value())
          as _i4.Future<_i2.GoogleSignInUserData?>);
  @override
  _i4.Future<_i2.GoogleSignInTokenData> getTokens(
          {String? email, bool? shouldRecoverAuth}) =>
      (super.noSuchMethod(
              Invocation.method(#getTokens, [],
                  {#email: email, #shouldRecoverAuth: shouldRecoverAuth}),
              returnValue: Future<_i2.GoogleSignInTokenData>.value(
                  _FakeGoogleSignInTokenData_0()))
          as _i4.Future<_i2.GoogleSignInTokenData>);
  @override
  _i4.Future<void> signOut() =>
      (super.noSuchMethod(Invocation.method(#signOut, []),
          returnValue: Future<void>.value(),
          returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
  @override
  _i4.Future<void> disconnect() =>
      (super.noSuchMethod(Invocation.method(#disconnect, []),
          returnValue: Future<void>.value(),
          returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
  @override
  _i4.Future<bool> isSignedIn() =>
      (super.noSuchMethod(Invocation.method(#isSignedIn, []),
          returnValue: Future<bool>.value(false)) as _i4.Future<bool>);
  @override
  _i4.Future<void> clearAuthCache({String? token}) => (super.noSuchMethod(
      Invocation.method(#clearAuthCache, [], {#token: token}),
      returnValue: Future<void>.value(),
      returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
  @override
  _i4.Future<bool> requestScopes(List<String>? scopes) =>
      (super.noSuchMethod(Invocation.method(#requestScopes, [scopes]),
          returnValue: Future<bool>.value(false)) as _i4.Future<bool>);
}
