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

使用ts-mockito模拟TypeScript对象时方法调用报错

使用ts-mockito时「Cannot read properties of null (reading 'methodStubCollection')」错误解决方法

问题场景

尝试用ts-mockito模拟对象实例的成员函数返回值时,抛出TypeError: Cannot read properties of null (reading 'methodStubCollection')错误;大型项目中还出现过mockObject.mockMethod is not a function类似报错。已确认调用了instance方法,但问题仍未解决,最小复现代码如下:

package.json

{
  "name": "dwf_backend",
  "version": "1.0.0",
  "description": "Server for DrawWithFriends app",
  "main": "index.js",
  "scripts": {
    "test": "jest --coverage",
    "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/server.js\"",
    "start": "ts-node src/index.ts"
  },
  "author": "TJ",
  "license": "ISC",
  "devDependencies": {
    "@types/jest": "^29.5.1",
    "jest": "^29.5.0",
    "ts-jest": "^29.1.0",
    "ts-mockito": "^2.6.1"
  }
}

测试代码

import { mock, instance, anything, when } from 'ts-mockito'

class B {
    public doTheThing(str: string): number {
        return str.length;
    }
}

class A {
    private readonly b: B;
    constructor(b: B) {
        this.b = b;
    }

    public doTheMainThing() {
        this.b.doTheThing('strrr');
    }
}

describe('test cases', () => {
    it('passes', () => {
    });

    it('mocks', () => {
        const mockedB: B = mock(B);
        const a = new A(instance(mockedB));
        a.doTheMainThing();
    });

    it('controls the mocked method', () => {
        const mockedB: B = mock(B);
        const instanceB: B = instance(mockedB);
        console.log(`instanceB is: ${JSON.stringify(instanceB)}`);

        // 错误:此处传入了instance生成的实例,而非mock对象
        when(instanceB.doTheThing(anything())).thenReturn(4);

        const a = new A(instanceB);
        a.doTheMainThing();
    });
});

错误原因

ts-mockito的核心使用规则:when方法必须接收mock()创建的模拟对象,而非instance()生成的代理实例。你在第三个测试用例中错误地将代理实例传入when,导致框架无法找到对应的方法存根集合,从而抛出空指针错误。

修复方案

将when的调用对象替换为mock()生成的mockedB,而非instance()生成的instanceB,修改后的测试代码如下:

import { mock, instance, anything, when } from 'ts-mockito'

class B {
    public doTheThing(str: string): number {
        return str.length;
    }
}

class A {
    private readonly b: B;
    constructor(b: B) {
        this.b = b;
    }

    public doTheMainThing() {
        this.b.doTheThing('strrr');
    }
}

describe('test cases', () => {
    it('passes', () => {
    });

    it('mocks', () => {
        const mockedB: B = mock(B);
        const a = new A(instance(mockedB));
        a.doTheMainThing();
    });

    it('controls the mocked method', () => {
        const mockedB: B = mock(B);
        // 正确:使用mock对象配置存根
        when(mockedB.doTheThing(anything())).thenReturn(4);
        
        const instanceB: B = instance(mockedB);
        const a = new A(instanceB);
        a.doTheMainThing();
    });
});

额外注意事项

  • 确保ts-mockito版本与jest、ts-jest版本兼容,当前ts-mockito@2.6.1适配jest@29.x无问题,版本升级时需注意兼容性。
  • instance()生成的代理实例仅用于注入到被测试对象中,不能用于配置存根逻辑。
  • 大型项目中若仍出现类似错误,检查是否有babel插件、其他测试工具干扰了ts-mockito的代理生成逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:08:15