You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter模拟AutoRouteObserver测试导航时出现MissingStubError(navigator)问题

错误原因
  • AutoRouteObserver继承自Flutter原生的NavigatorObserver类,该类自带navigator getter属性,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:18:04