Dart Mockito报UnimplementedError:hasFormTypeChanged异常排查
问题描述
我编写了如下单元测试用例:
test( 'Form is Edit, and value is different to form value, sets form type to Add, and sets hasFormTypeChanged to true', () async { manageVgnItmStore = MockManageVgnItmStore(); final formVm = MockManageVgnItmsFormStore(); when(formVm.hasFormTypeChanged).thenReturn(false); when(manageVgnItmStore?.lastSelectedVgnItm).thenReturn( const VgnItm.groceryItm(companyName: 'Cadbury', name: 'Chocolate')); when(manageVgnItmStore?.stateNotifiersVm) .thenReturn(ManageVgnItmsStateNotifiersStore(manageVgnItmStore!)); when(manageVgnItmStore?.formVm).thenReturn(formVm); when(manageVgnItmStore?.formVm.hasFormTypeChanged).thenReturn(false); when(manageVgnItmStore?.formType).thenReturn(const Edit(name: 'Edit')); underTest = VgnItmFormEvents(manageVgnItmStore!); underTest?.onNameChanged('fasdfsdfsdf', form!); verify(underTest?.manageVgnItmStore.formType = const Add(name: 'Add')); verify(underTest?.manageVgnItmStore.formVm.hasFormTypeChanged = true); });
执行测试时,最后一个verify调用抛出如下错误:
UnimplementedError: hasFormTypeChanged
package:test_api
Fake.noSuchMethod
package:vepo/src/presentation/stores/manage_vegan_items/form_store.dart
19:8 _FakeManageVgnItmsFormStore_0.hasFormTypeChanged
我已经多次对hasFormTypeChanged做了when打桩配置:
when(formVm.hasFormTypeChanged).thenReturn(false); when(manageVgnItmStore?.formVm.hasFormTypeChanged).thenReturn(false);
请问该UnimplementedError异常出现的原因是什么?
异常原因
- verify写法错误:mockito的
verify需要接收包含待验证调用的表达式,你直接把赋值语句写在verify括号里,会让Dart立即执行hasFormTypeChanged = true的赋值操作,而不是把调用交给mockito做校验。执行这个赋值的过程中会先访问underTest.manageVgnItmStore.formVm路径下的对象,直接触发未打桩的逻辑。 - 打桩顺序错误:你先执行了
when(manageVgnItmStore?.formVm.hasFormTypeChanged).thenReturn(false),这行代码运行时,还没有配置manageVgnItmStore.formVm的getter返回你手动创建的formVm实例,此时访问manageVgnItmStore.formVm拿到的是mockito自动生成的临时_FakeManageVgnItmsFormStore_0实例,你给这个临时实例打的桩完全不会作用到后续实际使用的formVm上。 - 仅打桩了getter,未处理setter:你所有的
when调用都是针对hasFormTypeChanged的读操作(getter),完全没有对写操作(setter)做配置。如果你的MockManageVgnItmsFormStore不是通过@GenerateMocks注解配合build_runner生成的标准mock类,而是手动继承Fake实现的,未重写的setter会默认走到noSuchMethod,抛出UnimplementedError。
内容的提问来源于stack exchange,提问作者BeniaminoBaggins
相关产品推荐
相关产品推荐

