javascript - 在节点中使用 JEST 模拟类
问题描述
所以,这实际上是我多次发生的事情,我从来不知道如何解决它。
我有这样的课
//myClass.js
const { get } = require('../models/myModel');
class MyClass {
constructor(id) {
this.id = id;
}
async getByID() {
return get(this.id);
}
}
和一个控制器
//controller.js
module.exports = MyClass;
const MyClass = require('./MyClass.js');
module.exports = {
getController: (req, res, next) => {
try {
const MyObject = new MyClass(1);
const info = await MyObject.getByID();
res.send(info)
}
catch (e) {
next(e);
}
}
}
当我想做一个 E2E 测试时,我需要模拟它getByID
以查看它解决和拒绝时会发生什么。
那么,如何模拟构造函数呢?我做了这样的事情
// myclass.spec.js
const MyClass = require('./MyClass.js');
jest.mock('./MyClass', () => jest.fn().mockImplementation(() => ({
getByID: Promise.resolve({id: 1, name: 'John'}),
})));
describe('Testing MyClass', () => {
it('Should return info', () => {
const res = httpMocks.createResponse();
const mReq = httpMocks.createRequest();
const mNext = jest.fn();
const mRes = mockResponse();
await pipelineController(mReq, mRes, mNext);
expect(mRes.send).toHaveBeenCalledWith(1);
done();
})
})
我知道这个测试目前有效,但现在我无法更改该getByID
模拟值以查看它拒绝承诺时会发生什么。
如果我尝试将它包含在测试(it
)中......它不会模拟任何东西......我想要类似的东西
const MyClass = require('./MyClass.js');
const {pipelineController} = require('./controllers.js')
jest.mock('./MyClass', () => jest.fn().mockImplementation(() => ({
getInfo: jest.fn(),
})));
describe('Testing MyClass', () => {
it('Should return info', () => {
ProcessService.getInfo.mockImplementation(() => Promise.resolve('the value i want'))
const res = httpMocks.createResponse();
const mReq = httpMocks.createRequest();
const mNext = jest.fn();
const mRes = mockResponse();
await pipelineController(mReq, mRes, mNext);
expect(mRes.send).toHaveBeenCalledWith(1);
done();
})
it('Should return info', () => {
ProcessService.getInfo.mockImplementation(() => Promise.reject('the reason i want'))
const res = httpMocks.createResponse();
const mReq = httpMocks.createRequest();
const mNext = jest.fn();
const mRes = mockResponse();
await pipelineController(mReq, mRes, mNext);
expect(mRes.send).toHaveBeenCalledWith(1);
done();
})
})
解决方案
由于getByID
在实例化后立即调用,因此应该在模拟类之外提供一个间谍以更改实现。
这可以通过以模糊和未指定方式工作的类自动模拟来完成,但可能适用于这种特定情况:
jest.mock('./MyClass.js')
const MyClass = require('./MyClass.js');
...
MyClass.prototype.getByID.mockResolvedValue({id: 1, name: 'John'});
// instantiate MyClass and call getByID
这可以通过在课堂外暴露一个间谍来完成:
const mockGetByID = jest.fn();
jest.mock('../../../services/ProcessService', () => jest.fn(() => (
{ getByID: mockGetByID }
)));
const MyClass = require('./MyClass.js');
...
mockGetByID.mockResolvedValue({id: 1, name: 'John'});
// instantiate MyClass and call getByID
推荐阅读
- excel - 如何将 XML API 响应转换为 Excel 表?
- javascript - 使用 mongoose 向 mongo dB 中的现有对象添加和额外的参数?
- asp.net-core - 数据复制或 API 网关聚合:使用微服务选择哪一个?
- r - R markdown csv文件数据导入
- javascript - Chart.js:不要将轴拉伸到图表之外
- python - 用于 EXPAND 和 MAKECAB 的 Python3 库或模块?
- angular - 如何使用角度解析处理我的getProduct请求中的html
- r - 使用“icenReg”包在 R 中进行间隔删失生存分析
- python - 如何以离线模式将python模块从一台服务器安装到另一台服务器
- django - 如何将 django 的默认 sqlite3 数据库更改为更高级的数据库,如 MySQL?