如何测试构造函数中调用的init()函数,然后调用其他异步函数

问题描述 投票:0回答:1

我在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()方法。

我尝试测试getData()函数通过不模拟init()函数并使用异步测试,但是我不确定 在测试中使用等待的位置作为函数是在从构造函数调用的init内嵌套和调用的。

it('should fetch data', async()=>{
   //some logic  
})
unit-testing async-await jestjs es6-class
1个回答
1
投票

您可以使用jest.spyOn(object, methodName)模拟您的SampleClass方法。我的测试环境是node,所以我在fetch对象上模拟了global方法。如果您的测试环境为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

© www.soinside.com 2019 - 2024. All rights reserved.