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

Angular+Akita单元测试时spec文件中selectAll链式调用and方法报错

错误根因

这个报错和官方文档是否过时无关,and是Jasmine间谍(Spy)对象的专属属性,你当前直接调用todosQuery.selectAll.and时,selectAll还是Akita Query的原生方法,原生方法上不存在and属性,因此抛出类型错误,官方文档的示例默认你已经提前将selectAll包装为Jasmine间谍对象。

解决方案

目前有三种常用的Query返回值模拟方式,按推荐优先级排序如下:

  • 优先选择:直接操作Store写入测试数据
    Akita的Query本身是响应式从Store读取数据,你不需要模拟Query的方法,直接给对应的Store写入测试数据即可,更贴近真实运行逻辑,无类型兼容问题:
    // 注入对应Store实例
    const todosStore = TestBed.inject(TodosStore);
    // 写入测试数据,Query的selectAll会自动返回该数据
    todosStore.set([createTodo(), createTodo()]);
    
  • 次选:Spy包装真实Query的方法
    如果你确实需要模拟方法返回值,不需要依赖真实Store数据,先获取Query实例后用spyOn包装对应方法即可:
    // 注入Query实例
    const todosQuery = TestBed.inject(TodosQuery);
    // 用spyOn包装selectAll方法,之后就可以调用and.returnValue设置返回值
    spyOn(todosQuery, 'selectAll').and.returnValue(of([createTodo(), createTodo()]));
    
  • 完全Mock Query实例
    如果你不想引入真实的Query/Store依赖,可以直接构造Spy对象替换注入项:
    // 构造Query的Spy对象
    const mockTodosQuery = jasmine.createSpyObj('TodosQuery', ['selectAll']);
    mockTodosQuery.selectAll.and.returnValue(of([createTodo(), createTodo()]));
    
    // TestBed配置中替换真实依赖
    providers: [
      { provide: TodosQuery, useValue: mockTodosQuery }
    ]
    

内容的提问来源于stack exchange,提问作者hhusnjak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:45:03