如何Mock类内部实例,验证TypeScript中BroadcastChannel的postMessage被调用
解决方案
你已经完成了broadcast-channel模块的mock,只需从mock构造函数的实例列表中获取服务内部创建的BroadcastChannel实例,即可拿到对应的postMessage mock方法完成断言。
修改后的完整测试代码如下:
import { BroadcastChannel } from 'broadcast-channel'; import { BroadcastChannelService } from '../../services'; jest.mock('broadcast-channel'); const mockedBroadcastChannel = BroadcastChannel as jest.Mocked<typeof BroadcastChannel>; describe('BroadcastChannelService', () => { let subject: BroadcastChannelService<string>; describe('constructor', () => { afterAll(() => { jest.resetAllMocks(); }); test('实例化成功', () => { subject = new BroadcastChannelService<string>('GOOGLE_AUTH'); expect(mockedBroadcastChannel).toBeCalledWith('GOOGLE_AUTH'); expect(mockedBroadcastChannel).toBeCalledTimes(1); }); }); describe('postMessage', () => { beforeAll(() => { // 清除之前构造函数的调用记录和遗留实例 mockedBroadcastChannel.mockClear(); subject = new BroadcastChannelService('GOOGLE_AUTH'); subject.postMessage('Hello World'); }); afterAll(() => { jest.resetAllMocks(); }); test('正确调用内部BroadcastChannel的postMessage方法', () => { // 取mock构造函数生成的第一个实例 const createdChannel = mockedBroadcastChannel.mock.instances[0]; expect(createdChannel.postMessage).toBeCalledTimes(1); expect(createdChannel.postMessage).toBeCalledWith('Hello World'); }); }); });
说明
- Jest mock类构造函数时,会自动为所有实例方法创建mock函数,所有生成的实例都会按实例化顺序存储在
mock.instances数组中,直接取用即可完成断言。 - 你也可以通过类型断言绕开私有属性限制直接访问服务内部的
broadcastChannel属性:expect((subject as any).broadcastChannel.postMessage).toBeCalledWith('Hello World'),但更推荐上述获取mock实例的方案,不需要依赖类内部的私有属性命名。
内容的提问来源于stack exchange,提问作者Gareth Kear
相关产品推荐
相关产品推荐

