我有一个下面的组件类,该组件类使用第三方npm模块创建其余和websocket连接。我可以将Component.constructor更改为接受模块作为依赖项,以便在Jest测试期间注入模拟版本。但是我读到有关用Jest制作Mocks的文章,我想我想尝试一下,但似乎无法理解如何截获Api.Rest()和Api.Websocket返回值。
// component.ts
import * as Api from 'npm-module'
import * as wait from 'wait-for-stuff' // actual npm module
export class Component {
private _rest:any;
private _websocket:any;
public events = new EventEmitter();
constructor() {
// I want to intecept the return value of
// Api.Rest() and Api.Websocket() to use mock versions.
this._rest = new Api.Rest();
this._websocket = new Api.Websocket();
this._init();
}
private _init() {
// so that when do stuff with this._rest and this._websocket;
// I can control what is the expected results during test
this._websocket.onUpdate((data) => {
events.emit('update', data);
});
var value = wait.for.promise(this._rest.getSomething());
}
}
我是否必须使用Sinon或Jasmine等其他测试库?
答案 0 :(得分:2)
以下是一个简化的工作示例,可以帮助您入门:
// @ts-ignore
import * as Api from 'npm-module'; // <= (ts-ignore since "npm-module" doesn't exist)
import EventEmitter from 'events';
jest.mock('npm-module', () => {
const getSomethingMock = jest.fn(); // <= always return...
const onUpdateMock = jest.fn(); // <= ...the same mocks...
return {
Rest: () => ({ getSomething: getSomethingMock }),
Websocket: () => ({ onUpdate: onUpdateMock })
}
},
{ virtual: true }); // <= (use virtual since "npm-module" doesn't exist)
class Component {
private _rest: any;
private _websocket: any;
public events = new EventEmitter();
constructor() {
this._rest = new Api.Rest();
this._websocket = new Api.Websocket();
this._init();
}
private _init() {
this._websocket.onUpdate((data) => { // <= ...so that this onUpdate...
this.events.emit('update', data);
});
}
}
test('Component', () => {
const component = new Component();
const listener = jest.fn();
component.events.on('update', listener);
const onUpdate = new Api.Websocket().onUpdate; // <= ...is the same as this one
const onUpdateArrowFunction = onUpdate.mock.calls[0][0]; // <= get the arrow function passed to it
onUpdateArrowFunction('mock data'); // <= now call the function
expect(listener).toHaveBeenCalledWith('mock data'); // Success!
});
详细信息
Jest
接管require
系统,并允许您指定需要模块时要返回的内容(请注意,TypeScript import
语句已编译为{{1} })。
模拟模块的一种方法是通过在require
上创建一个包含模拟的文件来创建manual mock。
另一种方法(如上所示)是使用jest.mock
并将其传递给模块工厂函数。
在测试期间__mocks__/npm-module.ts
每次需要模块时,都会返回模拟的模块。
请注意,上面的示例始终为Jest
和getSomething
返回相同的模拟,因此可以在测试过程中检索这些模拟函数。
还请注意使用mockFn.mock.calls
来检索此箭头功能:
onUpdate
...将其传递到(data) => {
this.events.emit('update', data);
}
。一旦检索到它,就可以直接调用它,从而按预期触发侦听器。