[英]Jest - Mock method of default class exported as named component of a package module
[英]Mock node external module default with chained method using jest
在我們的節點 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 來測試這種方法。 我們有兩個測試要實現:
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.start).toHaveBeenCalled();
甚至expect((ora as any).start).toHaveBeenCalled();
:
錯誤 TS2339:屬性 'start' 在類型 'typeof import("/Users/Dev/cli/node_modules/ora/index")' 上不存在。
肯定是因為ora
的類型定義是export default function ora(options?: Options | string): Ora;
那么如何在 jest 的節點測試環境中模擬像 ora 這樣的第三方?
你有幾個選擇:
你可以像這樣模擬ora
:
jest.mock('ora', () => {
const start = jest.fn();
const result = { start };
return jest.fn(() => result);
});
...然后調用ora
獲取它返回的對象(因為它總是返回相同的對象)並使用該對象訪問start
:
it('should call ora start', () => {
const result = ora();
expect(result.start).toHaveBeenCalled(); // Success!
});
或者,如果您願意,您可以將start
mock 作為屬性附加到ora
mock 作為在測試期間訪問它的一種簡單方法,如下所示:
const ora = require('ora');
jest.mock('ora', () => {
const start = jest.fn();
const result = { start };
const ora = jest.fn(() => result);
ora.start = start; // attach the start mock to ora
return ora;
});
const startSpinner = require('./startSpinner');
describe('startSpinner', () => {
beforeEach(() => {
startSpinner({});
});
describe('ora', () => {
it('should call ora', () => {
expect(ora).toHaveBeenCalled(); // Success!
});
it('should call ora start', () => {
expect(ora.start).toHaveBeenCalled(); // Success!
});
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.