Flutter模拟AutoRouteObserver测试导航时出现MissingStubError(navigator)问题
错误原因
AutoRouteObserver继承自Flutter原生的NavigatorObserver类,该类自带navigatorgetter属性,AutoRoute框架初始化导航器时会主动访问该属性- 你通过Mockito生成的
MockAutoRouteObserver默认没有对这个属性做存根配置,框架调用时就会抛出MissingStubError报错
解决方案
推荐按优先级选择以下方案:
方案1:手动添加navigator属性存根
这是成本最低的解决方式,直接在创建mockAutoRouterObserver后新增一行存根代码即可:
var mockAutoRouterObserver = MockAutoRouteObserver(); // 新增存根,返回null不影响导航逻辑执行 when(mockAutoRouterObserver.navigator).thenReturn(null);
AutoRoute内部仅对该属性做基础校验,返回null不会干扰你对didPush等导航事件的验证逻辑。
方案2:生成Mock时开启默认空返回
如果你使用Mockito的代码生成能力创建Mock类,可以在@GenerateMocks注解中开启returnNullOnMissingStub参数,所有未手动存根的方法/属性调用都会默认返回null,不会再抛出缺失存根的错误:
@GenerateMocks( [AutoRouteObserver], returnNullOnMissingStub: true, ) void main() { // 原有测试逻辑 }
该方案适合需要模拟的方法较多,不想逐个添加存根的场景。
方案3:手写Observer假实现(可选)
如果你仅需要验证didPush/didPop这类导航事件,也可以手动编写继承自AutoRouteObserver的实现类,重写需要验证的方法手动记录调用状态,无需依赖Mockito的模拟能力,稳定性更高。
修改后的测试核心代码示例:
void main() async { var authManagerMock = getAndRegisterAuthManagerMock(); var mockRepository = getAndRegisterRepositoryMock(); final _appRouter = AppRouterAutoRoute(authGuard: AuthGuard()); var mockAutoRouterObserver = MockAutoRouteObserver(); // 新增navigator存根 when(mockAutoRouterObserver.navigator).thenReturn(null); Widget makeTestableWidget() { when(authManagerMock.isLoggedIn()).thenAnswer((realInvocation) => false); return MaterialApp.router( routerDelegate: AutoRouterDelegate(_appRouter, navigatorObservers: () => [mockAutoRouterObserver]), routeInformationParser: _appRouter.defaultRouteParser()); } // 剩余测试逻辑不变 }
内容的提问来源于stack exchange,提问作者DieabeS
相关产品推荐
相关产品推荐

