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

Jasmine测试参数不匹配:如何Mock loadData与EventProvider类型的this?

Jasmine测试:Mock函数与EventProvider实例匹配问题

问题场景

控制器代码片段

const account = "abc", isIDValid = true, loadData = this.loadData, that = this;

let args = {account, isIDValid, loadData, that};

dialog.open(args);

测试用例代码

describe("when user click open dialog", function() {
    let account, isIDValid, loadData, that, args;
    beforeEach(function() {
        account = "abc";
        isIDValid = true;
        loadData = function() {};
        that = folder1.project.Controller;
        args = {account, isIDValid, loadData, that};
    });

    it("should call dialog with args", function() {
        controller.abc(isIDValid);
        expect(dialog.open).toHaveBeenCalledWith(args);
    });
});

报错信息

Expected spy open to have been called with:

  [ Object({ account: 'abc', isIDValid: true, loadData: Function, that: Function }) ]

but actual calls were:

  [ Object({ account: 'abc', isIDValid: true, loadData: Function, that: EventProvider folder1.project.Controller }) ].

解决方案

问题核心是测试中mock的loadData和that与控制器实际传递的引用/实例不匹配,调整方式如下:

1. 正确Mock loadData函数

不要单独定义空函数,直接Spy控制器实例上的loadData方法,确保测试使用的loadData和控制器里this.loadData是同一个引用:

spyOn(controller, 'loadData').and.callFake(function() {});

2. 匹配EventProvider类型的this

控制器里的that = this指向的是控制器的实例(EventProvider类型),测试中错误赋值为构造函数folder1.project.Controller,需改为使用控制器实例本身,或模拟一个符合EventProvider结构的实例。

修改后的测试用例示例

方案一:使用真实控制器实例

describe("when user click open dialog", function() {
    let args;
    beforeEach(function() {
        // Spy控制器实例的loadData方法
        spyOn(controller, 'loadData').and.callFake(function() {});
        // 使用控制器实例作为that(与控制器内的this一致)
        const that = controller;
        
        args = {
            account: "abc",
            isIDValid: true,
            loadData: controller.loadData,
            that: that
        };
    });

    it("should call dialog with args", function() {
        controller.abc(true);
        expect(dialog.open).toHaveBeenCalledWith(args);
    });
});

方案二:模拟EventProvider实例

describe("when user click open dialog", function() {
    let mockController, args;
    beforeEach(function() {
        // 创建模拟的EventProvider实例,包含loadData方法
        mockController = jasmine.createSpyObj('EventProvider', ['loadData']);
        mockController.loadData.and.callFake(function() {});
        
        args = {
            account: "abc",
            isIDValid: true,
            loadData: mockController.loadData,
            that: mockController
        };
        // 注入mock实例到控制器(根据实际初始化逻辑调整)
        controller = new folder1.project.Controller(mockController);
    });

    it("should call dialog with args", function() {
        controller.abc(true);
        expect(dialog.open).toHaveBeenCalledWith(args);
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:30:38