Flutter测试报错:Null类型无法转为Future<Either<Failure, NumberTrival>>
问题分析与解决方案
错误根源
该错误是因为Mockito的方法匹配未命中,导致mock的getConcreteNumberTrival方法返回了默认的Null,而非你定义的right(numberTrival)。常见触发场景包括:
- 命名参数的匹配格式不符合Mockito要求
- Mockito版本对Dart空安全支持不足
- 测试变量的初始化顺序或作用域问题
解决办法
1. 修正Mockito参数匹配逻辑
确保when语句中正确匹配命名参数,使用Mockito提供的匹配器精确命中:
// 精确匹配指定数值 when(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber))) .thenAnswer((_) async => right(numberTrival)); // 或者匹配任意命名参数(适用于不关心具体数值的场景) when(mockNumberTrivalRepository.getConcreteNumberTrival(number: anyNamed('number'))) .thenAnswer((_) async => right(numberTrival));
2. 升级Mockito版本
旧版Mockito对Dart空安全的支持存在缺陷,更新pubspec.yaml中的依赖:
dev_dependencies: mockito: ^5.4.0 # 或更高稳定版 flutter_test: sdk: flutter
执行flutter pub get完成依赖更新。
3. 调整变量初始化顺序
将测试变量移至setUp中,确保在测试执行前完成初始化:
void main() { late MockNumberTrivalRepository mockNumberTrivalRepository; late GetConcreteNumberTrival sut; late NumberTrival numberTrival; late int tNumber; setUp(() { mockNumberTrivalRepository = MockNumberTrivalRepository(); sut = GetConcreteNumberTrival(mockNumberTrivalRepository); numberTrival = NumberTrival(text: "text", number: 4); tNumber = 4; }); // 测试方法... }
4. 保持verify与when的参数匹配一致
确保verify语句的参数和when中的匹配规则完全相同:
verify(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber)));
完整修正后的测试代码
import 'package:dartz/dartz.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:number_trivia/core/failure/failure.dart'; import 'package:number_trivia/features/number_trivia/domain/entities/number_trival.dart'; import 'package:number_trivia/features/number_trivia/domain/repositories/number_trival_repository.dart'; import 'package:number_trivia/features/number_trivia/domain/usecases/get_concrete_number_trival.dart'; class MockNumberTrivalRepository extends Mock implements NumberTrivalRepository {} void main() { late MockNumberTrivalRepository mockNumberTrivalRepository; late GetConcreteNumberTrival sut; late NumberTrival numberTrival; late int tNumber; setUp(() { mockNumberTrivalRepository = MockNumberTrivalRepository(); sut = GetConcreteNumberTrival(mockNumberTrivalRepository); numberTrival = NumberTrival(text: "text", number: 4); tNumber = 4; }); test("get concrete number trivial", () async { when(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber))) .thenAnswer((_) async => right(numberTrival)); final result = await sut.execute(tNumber); expect(result, right(numberTrival)); verify(mockNumberTrivalRepository.getConcreteNumberTrival(number: eq(tNumber))); verifyNoMoreInteractions(mockNumberTrivalRepository); }); }
内容的提问来源于stack exchange,提问作者Suzan Aangboo
相关产品推荐
相关产品推荐

