使用Mockito做Dart单元测试时遇Null与Future<String>类型不匹配错误
问题根源与解决方案
问题出在哪?
你犯了两个关键错误:
- Mock类重复定义:同时手动编写了
MockMyService类,又使用@GenerateMocks([MyService])注解自动生成同名Mock类,导致类名冲突,实际运行时没有正确加载预期的Mock实现,最终调用未正确Stub的方法返回Null,触发类型转换错误。 - 注解位置错误:
@GenerateMocks注解被放在了main函数上方,正确位置应该是在文件顶部(import语句之后、main函数之前)。
修复方案(两种可选)
方案一:使用自动生成Mock类(推荐)
这是Mockito官方推荐的方式,避免手动编写Mock类的潜在问题:
- 删除手动编写的
class MockMyService extends Mock implements MyService {}代码块。 - 将
@GenerateMocks([MyService])注解移到main函数外部,放在文件顶部(import之后)。 - 确保导入必要依赖包:
import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; - 执行命令生成Mock类:
执行后会生成一个形如dart run build_runner build[你的文件名].mocks.dart的文件,无需手动修改,测试代码会自动关联它。 - 修改测试代码,直接使用生成的
MockMyService类:
完整代码示例:
import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; class MyService { Future<String> getData() async { return 'Real Data from Network'; } } @GenerateMocks([MyService]) void main() { late MockMyService mockMyService; setUp(() { mockMyService = MockMyService(); }); test('Test getData with stubbed response', () async { when(mockMyService.getData()).thenAnswer((_) async => "Mocked Data"); final result = await mockMyService.getData(); expect(result, 'Mocked Data'); verify(mockMyService.getData()).called(1); }); }
方案二:手动编写Mock类(适合简单场景)
如果不想使用自动生成工具,只需移除@GenerateMocks注解,保留手动Mock类即可:
完整代码示例:
import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; class MyService { Future<String> getData() async { return 'Real Data from Network'; } } class MockMyService extends Mock implements MyService {} void main() { late MockMyService mockMyService; setUp(() { mockMyService = MockMyService(); }); test('Test getData with stubbed response', () async { when(mockMyService.getData()).thenAnswer((_) async => "Mocked Data"); final result = await mockMyService.getData(); expect(result, 'Mocked Data'); verify(mockMyService.getData()).called(1); }); }
这种方式不需要执行build_runner命令,直接运行测试即可。
额外检查
确保你的pubspec.yaml中包含正确的开发依赖:
dev_dependencies: test: any mockito: ^5.4.0 # 可替换为最新稳定版本 build_runner: any
内容的提问来源于stack exchange,提问作者Supun Ayeshmantha
相关产品推荐
相关产品推荐

