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

Jasmine测试:如何验证作为参数传入的回调方法被正确执行

问题原因
  • 异步逻辑未等待就执行断言:axios.get返回的是Promise,其then回调属于微任务,会等待当前所有同步代码(也就是你写的expect断言)执行完毕后才会运行。你执行断言时onSuccess回调根本还没有被触发,所以测试失败,而控制台后续打印出foo是因为测试跑完之后微任务才正式执行。
  • 验证方式冗余:不需要绕到console.log间接验证回调触发,直接给onSuccess本身创建spy更直观,也能避免函数调用上下文带来的监听偏差。
修复后的测试代码

推荐用Jasmine的async/await方案处理异步测试,代码更简洁:

// agency_controller.spec.js
import { getProducerNamesAndBillingPlan } from "../../../../app/javascript/packs/controllers/agencies_controller";
import axios from 'axios';

const mockAxiosPromise = (response) => {
  return Promise.resolve({ status: 200, data: response});
}

describe('#getProducerNamesAndBillingPlan', () => {
  it('calls the given onSuccess method if the request is successful', async () => {
    // 直接mock axios.get返回结果
    spyOn(axios, 'get').and.returnValue(mockAxiosPromise('foo'));
    // 给onSuccess创建专用spy,监听调用情况
    const mockOnSuccess = jasmine.createSpy('mockOnSuccess');

    getProducerNamesAndBillingPlan({ agencyId: 1, onSuccess: mockOnSuccess });

    // 等待所有已入队的微任务(包括axios的then回调)执行完成
    await Promise.resolve();

    // 直接断言回调被调用且参数正确
    expect(mockOnSuccess).toHaveBeenCalledOnceWith('foo');
  });
})

也可以用Jasmine的done回调方案实现相同效果:

it('calls the given onSuccess method if the request is successful', (done) => {
  spyOn(axios, 'get').and.returnValue(mockAxiosPromise('foo'));
  const mockOnSuccess = jasmine.createSpy('mockOnSuccess').and.callFake(() => {
    expect(mockOnSuccess).toHaveBeenCalledOnceWith('foo');
    // 回调执行后调用done,告知Jasmine异步测试完成
    done();
  });

  getProducerNamesAndBillingPlan({ agencyId: 1, onSuccess: mockOnSuccess });
})

内容的提问来源于stack exchange,提问作者N. Cashman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:15:01