如何用Dart Mockito模拟继承扩展的类?
在Dart中用Mockito模拟继承类的解决方案
针对你遇到的问题——模拟继承链中的Poodle类(继承自Dog,Dog又继承自Animal)并解决构造器运行时错误,以下是几种简洁的实现方式:
错误原因分析
你编写的FakePoodle继承Fake并实现Poodle时,使用super.emoji会触发错误,因为Fake类本身没有接收emoji的构造参数,无法传递该值。Fake是Mockito提供的快速实现接口的基类,但不会自动处理被实现类的父类属性与构造逻辑。
方案1:手动实现Fake类,维护父类属性
手动维护Poodle及父类的属性,配合Fake完成方法的空实现,即可正常进行调用验证:
class FakePoodle extends Fake implements Poodle { @override final String emoji; FakePoodle(this.emoji); // 无需实现具体逻辑,Fake会自动生成空实现,Mockito可正常拦截调用 @override String greet() => super.greet(); }
修改后测试代码即可正常运行,verify(fakePoodle.greet())能正确记录方法调用次数。
方案2:使用Mockito代码生成(推荐)
Mockito的代码生成功能可自动处理类的继承结构,无需手动编写Fake类,步骤如下:
- 添加依赖:在
pubspec.yaml的dev_dependencies中添加:
mockito: ^5.4.0 build_runner: ^2.4.4
- 编写测试并生成Mock类:在测试文件顶部添加注解,运行生成命令:
import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'your_animal_file.dart'; import 'your_test_file.mocks.dart'; // 生成的Mock文件 // 注解指定要生成Mock的类 @GenerateMocks([Poodle]) void main() { group('Dog tests', () { // ... 原有测试 test('Mock Poodle should greet only once', () { final mockPoodle = MockPoodle(); // 按需设置属性或方法返回值 when(mockPoodle.emoji).thenReturn('🐕'); when(mockPoodle.greet()).thenReturn('🐕: Woof!'); mockPoodle.greet(); // 验证调用次数 verify(mockPoodle.greet()).called(1); }); }); }
- 执行生成命令:在终端运行:
dart run build_runner build
生成的MockPoodle会自动处理继承关系,无需手动维护属性与方法。
方案3:使用Spy包装真实对象(保留真实逻辑)
如果你需要保留Poodle的真实业务逻辑,同时验证方法调用,可使用Mockito的spy功能:
test('Spy Poodle should greet only once', () { final realPoodle = Poodle('🐕'); final spyPoodle = spy(realPoodle); spyPoodle.greet(); // 验证调用次数 verify(spyPoodle.greet()).called(1); // 真实逻辑仍会执行,返回正确结果 expect(spyPoodle.greet(), '🐕: Woof!'); });
这种方式适用于需要复用真实类行为,同时监控方法调用的场景。
内容的提问来源于stack exchange,提问作者matox
相关产品推荐
相关产品推荐

