使用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
相关产品推荐
相关产品推荐

