【发布时间】:2019-08-21 13:21:14
【问题描述】:
在我们的节点 CLI 中,我们有一个简单的方法:
'use strict';
const ora = require('ora');
module.exports = function startSpinner({ textOnStart, color, spinnerType }) {
const spinner = ora({
text: textOnStart,
color: color || 'cyan',
spinner: spinnerType || ''
}).start();
};
我们尝试用 jest 来测试这个方法。我们有两个测试要实现:
- 测试是否使用正确的对象参数调用了 ora
- 测试
start()方法是否被调用
话虽如此,我们无法正确模拟 ora 模块。
ora是第三方,基本构造如下:
class Ora {
constructor(options){}
start(){ }
}
const oraFactory = function (opts) {
return new Ora(opts);
};
module.exports = oraFactory;
module.exports.default = oraFactory;
我们正在寻找一种模拟 ora 的方法。
我们尝试使用自动模拟:
const ora = require('ora');
jest.mock('ora');
const startSpinner = require('./startSpinner');
describe('startSpinner', () => {
beforeEach(() => {
startSpinner({});
});
describe('ora', () => {
it('should call ora', () => {
expect(ora).toHaveBeenCalled();
});
it('should call ora start', () => {
expect(ora.start).toHaveBeenCalled();
});
});
});
但两个测试分别失败:
匹配器错误:接收到的值必须是模拟或间谍函数
Received has type: function Received has value: [Function oraFactory]
和
匹配器错误:接收到的值必须是模拟或间谍函数
Received has value: undefined
我们尝试使用自定义模拟:
const ora = require('ora');
jest.mock('ora', () => {
return jest.fn().mockImplementation(() => {
return { start: jest.fn() };
});
});
最终得到完全相同的结果。
我们甚至尝试将我们的测试转换为打字稿,然后使用:
import * as ora from 'ora';
const startMock = jest.fn();
jest.mock('ora', () => {
return jest.fn().mockImplementation(() => {
return { start: startMock };
});
});
然后我们能够成功测试 ora 被调用。但我们最终得到了expect(ora.start).toHaveBeenCalled(); 甚至expect((ora as any).start).toHaveBeenCalled(); 的错误:
错误 TS2339:类型“typeof”上不存在属性“start” import("/Users/Dev/cli/node_modules/ora/index")'.
肯定是导入的ora的类型定义是export default function ora(options?: Options | string): Ora;造成的
如何在 jest 的节点测试环境中模拟像 ora 这样的第三方?
【问题讨论】:
标签: javascript node.js jestjs