如何解决Flutter - Mockito - 在测试中使用 async 会产生错误,但使用 async* 使它正常工作?
简而言之,我正在学习 ResoCoder TDD 课程。该课程有点过时,但我很确定跟随并在此过程中进行调整是没问题的。本课程的课程和 GitHub 中的代码不是空安全的。
而且我并没有完全按照课程进行。我在这里和那里做了一些更改。
我刚开始学习第 2 集或第 3 集的上下文。
auth_usecases_test.dart
import 'package:dartz/dartz.dart';
import 'package:mockito/mockito.dart';
import 'package:storayge/core/auth/domain/entities/local_user.dart';
import 'package:storayge/core/auth/domain/repository/auth_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:storayge/core/auth/domain/usecases/auth_usecases.dart';
class MockAuthRepository extends Mock implements AuthRepository {}
void main() {
late GetLocalUserDataFromRemote usecase;
late MockAuthRepository mockAuthRepository;
late String tUid;
late LocalUser tLocalUser;
setUp(() {
mockAuthRepository = MockAuthRepository();
usecase = GetLocalUserDataFromRemote(repository: mockAuthRepository);
tLocalUser = const LocalUser(
username: 'testUsername',email: 'testEmail@Email',uid: 'testUid',);
tUid = 'testUid';
});
test(
'should get LocalUser data from the repository',() async* {
// arrange
when(mockAuthRepository.getLocalUserDataFromRemote(uid: tUid))
.thenAnswer((_) async => Right(tLocalUser));
// act
final result = await usecase(Params(uid: tUid));
// assert
expect(result,equals(Right(tLocalUser)));
verify(mockAuthRepository.getLocalUserDataFromRemote(uid: tUid));
verifyNoMoreInteractions(mockAuthRepository);
},);
}
这是“工作”代码。如果我将 async*
关键字更改为仅 async
,则会产生以下错误:
type 'Null' is not a subtype of type 'Future<Either<Failure,LocalUser>>'
auth_usecases.dart
class GetLocalUserDataFromRemote implements Usecase<LocalUser,Params> {
final AuthRepository repository;
GetLocalUserDataFromRemote({required this.repository});
@override
Future<Either<Failure,LocalUser>> call(Params params) async {
return repository.getLocalUserDataFromRemote(uid: params.uid);
}
}
class Params extends Equatable {
final String uid;
Params({required this.uid});
@override
List<Object?> get props => [uid];
}
auth_repository.dart
import 'package:dartz/dartz.dart';
import '../../../errors/failures.dart';
import '../entities/local_user.dart';
abstract class AuthRepository {
Future<Either<Failure,LocalUser>> getLocalUserDataFromRemote({
required String uid,});
Future<Either<Failure,LocalUser>> signInWithEmailAndPassword({
required String email,required String password,});
}
local_user.dart
class LocalUser extends Equatable {
final String username;
final String email;
final String uid;
const LocalUser({
required this.username,required this.email,required this.uid,});
@override
List<Object?> get props => [username,email,uid];
}
failures.dart
abstract class Failure extends Equatable {
final List<Object> properties;
const Failure({required this.properties});
@override
List<Object> get props => properties;
}
为什么以及如何更改 async 标签使其起作用?我被难住了。
编辑:我的包裹目前都是最新的,具有零安全性。除了我使用 0.1.0-nullsafety.1 的 dartz
编辑 2:一些更新。首先,似乎使用 async* 标签使测试通过,但它似乎并没有实际工作。我的意思是测试通过了,即使它不应该通过。我想我已经找到了解决办法。这当然是我的错。 mockito 文档说 mockito 确实支持空安全,但有一些代码生成。使用自定义模拟类等等。我什么都没做,这很愚蠢,我讨厌自己。所以我会做一些事情,稍后再更新。
解决方法
好的。我终于找到了答案。是的,这是我自己的愚蠢错误。 基本上,mockito 5.0.0 现在确实支持空安全,但有一些警告。您将需要使用一些代码生成来生成模拟类。我没有。基本上我所做的是
class MockAuthRepository extends Mock implements AuthRepository {} // remove
@GenerateMocks([AuthRepository]) //new
void main() {
late GetLocalUserDataFromRemote usecase;
late MockAuthRepository mockAuthRepository;
late String tUid;
late LocalUser tLocalUser;
setUp(() {
mockAuthRepository = MockAuthRepository();
usecase = GetLocalUserDataFromRemote(repository: mockAuthRepository);
tLocalUser = const LocalUser(
username: 'testUsername',email: 'testEmail@Email',uid: 'testUid',);
tUid = 'testUid';
});
test(
'should get LocalUser data from the repository',() async {
// arrange
when(mockAuthRepository.getLocalUserDataFromRemote(anyNamed('uid')))
.thenAnswer((_) async => Right(tLocalUser));
// act
final result = await usecase(Params(uid: tUid));
// assert
expect(result,equals(Right(tLocalUser)));
verify(mockAuthRepository.getLocalUserDataFromRemote(uid: tUid));
verifyNoMoreInteractions(mockAuthRepository);
},);
}
并使用构建运行器生成它。这很容易。我就是那么笨,没有仔细阅读文档。
,我认为这是一个模拟失败。
尝试以这种方式调用您的代码作为 mockito docs 状态:
// arrange
when(mockAuthRepository.getLocalUserDataFromRemote(uid: anyNamed('uid')))
.thenAnswer((_) async => Right(tLocalUser));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。