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

PhantomJS/Sinon环境下如何正确Stub Promise解决.done调用报错问题

问题原因解析

a) 报错根因

你当前对SERVICE_ACCESSOR.makeCall的Stub仅返回了空对象{},但业务代码中会链式调用该方法返回值的.done()和.fail()方法,空对象不存在这两个方法,因此触发类型错误。报错中出现的callService应为代码笔误,实际对应业务逻辑中的makeCall方法,问题本质一致。

b) 未定义对象说明

报错中提到的未定义对象是.done方法。SERVICE_ACCESSOR.makeCall(params)返回空对象后,访问空对象的done属性得到undefined,将undefined作为函数调用就会抛出该错误。

正确Stub/Mock实现方案

你需要让makeCall的返回值模拟jQuery Deferred Promise的接口,提供.done、.fail方法,同时主动触发回调才能让unlock方法被调用,通过测试断言。另外你原有的LOCKER mock存在参数传递缺失的问题,也需要同步修正,修改后的setup代码如下:

var setup = function() {
    P.mock('service-accessor', function () {
        return {
            makeCall: sinon.stub().returns({
                done: function(successCallback) {
                    // 模拟请求成功,触发成功回调,可自定义传入测试用的返回数据
                    successCallback({code: 0, msg: "success"});
                    // 返回自身支持链式调用,保证后续.fail方法可以正常执行
                    return this;
                },
                fail: function(failCallback) {
                    // 若需要测试失败场景,可在这里主动触发fail回调
                    return this;
                }
            })
        };
    });
    P.mock('locker', function () {
        var methods = {
            execute: function (lockId, wrapped) {
                console.log('locked - ' + lockId)
                // 原逻辑未传递unlock参数,会导致业务代码中的unlock为undefined,此处补充传入
                wrapped(methods.unlock)
            },
            unlock: sinon.stub()
        };
        return {
            execute: methods.execute,
            unlock: methods.unlock
        };
    });
    P.start();
}

上述修改完成后即可跑通成功路径的测试,若需要测试失败场景,只需调换回调触发逻辑,在.fail中触发回调、.done中仅返回自身即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:48:02