我试图做单元测试与Supabase在扑动像下面的代码:
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>());
});
});
}
会抛出以下错误:....
类型'Null'不是类型'GoTrueClient'的子类型
我如何可以模拟或做单元测试与颤振Supabase功能?
你可以像这样使用Fake类:
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: 'test@gmail.com',
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,
);
}
}
添加到上面所说的模拟响应,如Stream<AuthState>
,这是onAuthStateChange函数的返回类型,并且您,例如想要测试您的逻辑如何响应不同的认证响应,您可以实现静态方法,返回您希望代码处理的不同状态:
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: 'test@example.com',
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
然后你可以在你的测试文件中使用它,通过导入fixture,然后调用任何一个静态方法,像这样:SupabaseAuthFixture.authenticated()
,我现在有一个supabase兼容的模拟类型,我可以在我的单元测试中使用,希望这有助于!!