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

如何在测试中模拟B类中实例化的外部Session类?

问题场景

现有以下TypeScript文件结构:

// A.ts
export abstract class A {
    protected abstract method1(arg);
}

// Session.ts(外部类)
export class Session {
    constructor(socket: WebSocket) {
        this._socket = socket;
        this._socket.on('close', () => { /* 业务逻辑 */ });
        this._socket.on('error', () => { /* 业务逻辑 */ });
        this._socket.on('message', () => { /* 业务逻辑 */ });
    }
    setSomeSocket(someSocket: WebSocket) {
        this._anotherSocket = someSocket;
        this._anotherSocket.on('close', () => { /* 业务逻辑 */ });
        this._anotherSocket.on('error', () => { /* 业务逻辑 */ });
    };
}

// B.ts
export class B extends A {
    protected async method1(arg) {
        try {
            let tempSession = new Session(socket);
            tempSession.setSomeSocket(socket);
            // 其他业务逻辑
        } catch(exception) {
            // 异常处理
        }
    }
}

// B.spec.ts(原测试文件)
describe("B test", () => {
    it("some test", async () => {
        const varB = new B();
        await varB["method1"](arg);
        expect(spied).toBeCalledTimes(1);
    });
})

需求:在B.spec.ts中模拟外部的Session类,避免其内部的socket.on()操作引发测试问题,确保B的method1调用的是模拟后的Session实例。

解决方案(基于Jest测试框架)

1. 模拟Session模块

在测试文件顶部,通过Jest的jest.mock()方法完全替换原Session模块的导出,替换为自定义的模拟类。

2. 定义模拟类逻辑

模拟的Session类保留原类的构造函数和setSomeSocket方法,但移除所有WebSocket事件绑定逻辑,避免测试时触发不必要的操作,同时用jest.fn()包裹方法以便后续验证。

3. 验证模拟效果

通过Jest的断言方法,验证B的method1是否正确调用了Session的构造函数和相关方法。

修改后的B.spec.ts代码如下:

// B.spec.ts
import { B } from './B';
// 模拟Session模块,替换为自定义实现
jest.mock('./Session', () => {
    return {
        Session: jest.fn().mockImplementation(() => {
            return {
                setSomeSocket: jest.fn() // 模拟setSomeSocket方法,空实现
            };
        })
    };
});

// 导入模拟后的Session类
import { Session } from './Session';

describe("B test", () => {
    it("some test", async () => {
        const varB = new B();
        // 执行测试方法
        await varB["method1"](/* 传入测试用的arg参数 */);
        
        // 验证Session构造函数是否被调用
        expect(Session).toHaveBeenCalledTimes(1);
        // 验证setSomeSocket方法是否被调用
        const mockSessionInstance = Session.mock.results[0].value;
        expect(mockSessionInstance.setSomeSocket).toHaveBeenCalledTimes(1);
    });
})

说明

  • jest.mock('./Session', ...)会覆盖原模块的导出,确保B在测试时使用的是模拟类而非真实的Session。
  • 若需要模拟方法的返回值或特定逻辑,可以在mockImplementation中自定义逻辑。
  • 通过jest.fn()生成的模拟函数,支持验证调用次数、传入参数等断言操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:45:56