skip to Main Content

I’m trying to do unit test with Supabase in Flutter like the code bellow:

import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:supabase_flutter/supabase_flutter.dart';


class TestMClass {
  SupabaseClient client;
  TestMClass({
    required this.client,
  });
  Future<AuthResponse> signinMc() async {
    final respnse = await client.auth
        .signInWithPassword(email: 'example@gmail', password: 'password');
    return respnse;
  }
}

class MockSupabaseClient extends Mock implements SupabaseClient {}

void main() async {
  
  final MockSupabaseClient mockClient = MockSupabaseClient();

  final TestMClass testMCass = TestMClass(client: mockClient);
  setUp(() {});
  group('TestAuthBloc', () {
    test('description', () async {
      final auth = await testMCass.signinMc();
      expect(auth, isA<AuthResponse>());
    });
  });
}

it throw this error:….

type ‘Null’ is not a subtype of type ‘GoTrueClient’

how I can Mock or do unit testing for Supabase functions with Flutter?

2

Answers


  1. You can use Fake class like this:

    import 'package:flutter_test/flutter_test.dart';
    import 'package:supabase/supabase.dart';
    
    void main() {
      test('Fake Supabase', () async {
        final supabase = FakeSupabase();
    
        final response = await supabase.auth.signInWithPassword(
          email: '[email protected]',
          password: 'passsword',
        );
        expect(response.session, isA<Session>());
      });
    }
    
    class FakeSupabase extends Fake implements SupabaseClient {
      @override
      get auth => FakeGotrue();
    }
    
    class FakeGotrue extends Fake implements GoTrueClient {
      final _user = User(
        id: 'id',
        appMetadata: {},
        userMetadata: {},
        aud: 'aud',
        createdAt: DateTime.now().toIso8601String(),
      );
      @override
      Future<AuthResponse> signInWithPassword(
          {String? email,
          String? phone,
          required String password,
          String? captchaToken}) async {
        return AuthResponse(
          session: Session(
            accessToken: '',
            tokenType: '',
            user: _user,
          ),
          user: _user,
        );
      }
    }
    
    Login or Signup to reply.
  2. To Add to what was said above for mocking responses such as Stream<AuthState> which is the return type from the onAuthStateChange function, and you, for example wanted to test how your logic responds to different auth responses you can implement static methods that return the different states you want your code to handle:

    import 'package:supabase_flutter/supabase_flutter.dart';
    import 'package:equatable/equatable.dart';
    // ^^ For Testing Value Equality, since flutter doesn't have that out of the box
    // which is something you'll probably want for unit testing
    
    class SupabaseAuthFixture extends Equatable {
      static Stream<AuthState> unauthenticated() async* {
    // ^^ static means we can call it without an instance of the class
    // ^^ and the async* syntax allows us to return the stream type
        const user = User(
          id: '',
          email: '',
          appMetadata: {},
          userMetadata: {},
          aud: '',
          createdAt: "",
          updatedAt: "",
        );
        const session = Session(
          accessToken: '',
          refreshToken: '',
          expiresIn: 0,
          tokenType: '',
          user: user,
        );
    
        yield AuthState(AuthChangeEvent.userDeleted, session);
      }
    
      static Stream<AuthState> authenticated() async* {
        final user = User(
          id: 'id',
          email: '[email protected]',
          appMetadata: {},
          userMetadata: {},
          aud: 'aud',
          createdAt: DateTime.now().toIso8601String(),
          updatedAt: DateTime.now().toIso8601String(),
        );
        final session = Session(
          accessToken: 'access_token',
          refreshToken: 'refresh_token',
          expiresIn: 3600,
          tokenType: 'bearer',
          user: user,
        );
        yield AuthState(AuthChangeEvent.signedIn, session);
      }
    
      @override
      List<Object?> get props => [unauthenticated(), authenticated()];
    }
    // ^^ For Equatable
    
    

    And you can then use it in your test files by importing the fixture and then calling any one of the static methods like this: SupabaseAuthFixture.authenticated() and I now have a supabase compliant mock type that I can use in my unit tests, hope this helps!!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search