如何在开玩笑中测试从构造函数调用然后调用其他异步函数的 init() 函数



我在javascript中有以下代码:

class SampleClass {
constructor(param1) {
this.param1 = param1;
this.init();
}
async init() {
await this.getData();
this.loadIframe();
}
async getData() {
const response = fetch(url);
const data = response.json();
//set the response to class variable
this.param2 = data;
}
loadIframe() {
//some logic to load iframe.
}
}

使用笑话测试它的最佳方法是什么?

目前,我正在通过模拟 init(( 函数来测试构造函数逻辑。

但我还必须测试 getData((函数。测试getData((方法的方法应该是什么。

我尝试通过不模拟 init(( 函数并使用异步测试来测试 getData(( 函数,但我不确定在测试中在哪里使用 await,因为该函数是嵌套的,并从从构造函数调用的 init 中调用。

it('should fetch data', async()=>{
//some logic  
})

你可以使用 jest.spyOn(object, methodName( 来模拟你的SampleClass方法。我的测试环境是node,所以我在global对象上模拟fetch方法。如果测试环境browser,则fetch方法位于window对象上。

例如

sampleClass.js

class SampleClass {
constructor(param1) {
this.param1 = param1;
this.init();
}
async init() {
await this.getData();
this.loadIframe();
}
async getData() {
const url = 'https://stackoverflow.com/';
const response = fetch(url);
const data = response.json();
this.param2 = data;
}
loadIframe() {}
}
export { SampleClass };

sampleClass.test.js

import { SampleClass } from './sampleClass';
describe('60146073', () => {
afterEach(() => {
jest.restoreAllMocks();
});
describe('#constructor', () => {
it('should consturt', () => {
jest.spyOn(SampleClass.prototype, 'constructor');
jest.spyOn(SampleClass.prototype, 'init').mockReturnValueOnce();
const instance = new SampleClass('param1');
expect(instance.param1).toBe('param1');
expect(instance.init).toBeCalledTimes(1);
});
});
describe('#init', () => {
it('should init', async () => {
jest.spyOn(SampleClass.prototype, 'getData').mockResolvedValueOnce();
jest.spyOn(SampleClass.prototype, 'loadIframe').mockReturnValueOnce();
jest.spyOn(SampleClass.prototype, 'init').mockReturnValueOnce();
const instance = new SampleClass();
await instance.init();
expect(instance.getData).toBeCalledTimes(1);
expect(instance.loadIframe).toBeCalledTimes(1);
});
});
describe('#getData', () => {
it('should fetch data', async () => {
const mResponse = { json: jest.fn().mockReturnValueOnce({}) };
global.fetch = jest.fn().mockResolvedValueOnce(mResponse);
jest.spyOn(SampleClass.prototype, 'init').mockReturnValueOnce();
const instance = new SampleClass();
await instance.getData();
expect(global.fetch).toBeCalledWith('https://stackoverflow.com/');
expect(mResponse.json).toBeCalledTimes(1);
});
});
});

100% 覆盖率的单元测试结果:

PASS  stackoverflow/60146073/sampleClass.test.js
60146073
#constructor
✓ should consturt (3ms)
#init
✓ should init (2ms)
#getData
✓ should fetch data (2ms)
----------------|---------|----------|---------|---------|-------------------
File            | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------|---------|----------|---------|---------|-------------------
All files       |     100 |      100 |      80 |     100 |                   
sampleClass.js |     100 |      100 |      80 |     100 |                   
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.137s, estimated 5s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60146073

最新更新