我见过类似的问题,但我在文档或stackoverflow中看到的任何内容都没有描述我正在尝试做什么。我是javascript的新手,刚刚开始使用jest,我已经通读了jest文档,但我还没有看到模拟外部库命名导出的示例。我试图模拟的库是速率限制器灵活的。我想嘲笑命名的导出 RateLimiterRedis。我需要模拟几个 RateLimiterRedis 函数,包括 get、consumption 和 delete。
例如,当我从redis嘲笑一个函数时,我所要做的就是:
import redis from 'redis';
jest.mock('redis', () => {
return { createClient: jest.fn()};
});
当我尝试时:
jest.mock('rate-limiter-flexible', () => {
return jest.fn().mockImplementation(() => {
return { RateLimiterRedis: { get: mockGet } }
});
});
我得到: 类型错误: _rateLimiterFlexible.RateLimiterRedis 不是构造函数
当我尝试时:
jest.mock('rate-limiter-flexible', () => {
return { RateLimiterRedis: () => {}}
});
我得到:TypeError:limiter.get 不是一个函数
所以它识别构造函数,但我需要添加函数。
我试过:
jest.mock('rate-limiter-flexible', () => {
return { RateLimiterRedis: () => {
return jest.fn().mockImplementation(() => {
return {
get: mockGet
}
})
},
}
});
这也给出了:TypeError: limiter.get 不是一个函数
这是我正在尝试测试的文件中:
const limiter = new RateLimiterRedis(opts);
我也尝试过 doMock 命名导出本身(因为模拟将自己提升到顶部(但没有成功
我的问题归结为,当该类是外部库的命名导出时,我如何模拟类的构造函数并且该类以开玩笑的方式运行?
编辑:
mock获取定义:
const mockIpAndUrl ={
consumedPoints:1
};
const mockGet = jest.fn().mockImplementation(() => {
return mockIpAndUrl;
})
这不起作用:
const mockIpAndUrl ={
consumedPoints:1
};
const mockGet = jest.fn().mockImplementation(() => {
return mockIpAndUrl;
})
jest.mock('rate-limiter-flexible', () => {
return{
RateLimiterRedis: jest.fn().mockImplementation(() => {
return { get : mockGet};
})
}
});
类型错误:limiter.get 不是一个函数
但是,这确实:
jest.mock('rate-limiter-flexible', () => {
return{
RateLimiterRedis: jest.fn().mockImplementation(() => {
return { get : jest.fn().mockImplementation(() => {
return mockIpAndUrl;
})};
})
}
});
这是我所指的文档: https://jestjs.io/docs/en/es6-class-mocks#calling-jestmockdocsenjest-objectjestmockmodulename-factory-options-with-the-module-factory-parameter
这让我相信我可以使用 mockGet
rate-limiter-flexible
的导出是一个对象,它应该具有RateLimiterRedis
函数,该函数返回具有get
方法的实例。
"我试过了"片段是错误的,因为它使RateLimiterRedis
函数返回另一个函数,并且RateLimiterRedis
本身不是间谍,因此无法断言。
它应该是:
jest.mock('rate-limiter-flexible', () => {
return {
RateLimiterRedis: jest.fn().mockImplementation(() => ({
get: mockGet
})
};
});
如果在顶级导入中实例化RateLimiterRedis
,则在模拟中访问mockGet
之前无法分配。它可以导出为模拟模块的一部分:
jest.mock('rate-limiter-flexible', () => {
const mockRateLimiterRedisGet = jest.fn();
return {
mockRateLimiterRedisGet,
RateLimiterRedis: jest.fn().mockImplementation(() => ({
get: mockRateLimiterRedisGet
})
};
});
这允许从测试中的rate-limiter-flexible
导入mockRateLimiterRedisGet
,并用于动态模拟的值和断言:
mockRateLimiterRedisGet.mockReturnValue(...);
...
expect(mockRateLimiterRedisGet).toBeCalled();