开玩笑的模拟未涵盖函数或返回错误

时间:2019-11-13 17:04:55

标签: javascript mocking jestjs

我正在尝试为csvtojson编写一个开玩笑的模拟测试,但是却出现错误:

  

TypeError:无法读取未定义的属性“ subscribe”

api.js:

import csv = require('csvtojson')
const request = require('request')

export const getApiData = url => {
  return csv()
   .fromStream(request.get(url)
   .subscribe(json => json)
}

api.test.js

import { getApiData } from '../api';
const csv = require('csvtojson');

jest.mock('csvtojson', () => {
  const fromStream = jest.fn();
  const subscribe = jest.fn(() => new Promise(resolve => setTimeout(resolve, 0)));
  const result = { fromStream, subscribe };
  return jest.fn(() => result);
});
jest.mock('request', () => {
  return { get: jest.fn() };
});
describe('getApiData', () => {
  beforeEach(() => {
    getApiData('http://test.com');
  });
  describe('csv', () => {
    expect(csv).toHaveBeenCalled();
  });
});

然后,当我从fromStream函数中删除getApiData时,我进行了测试,但是它的覆盖范围显示json => json没有被调用。

我真的很困惑。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

这是单元测试解决方案:

api.js

const csv = require('csvtojson');
const request = require('request');

export const getApiData = url => {
  return csv()
    .fromStream(request.get(url))
    .subscribe(json => json);
};

api.test.js

import { getApiData } from './api';
const csv = require('csvtojson');
const request = require('request');

jest.mock('csvtojson', () => {
  const mCsvtojson = {
    fromStream: jest.fn().mockReturnThis(),
    subscribe: jest.fn()
  };
  return jest.fn(() => mCsvtojson);
});
jest.mock('request', () => {
  return { get: jest.fn() };
});

describe('getApiData', () => {
  it('csv', done => {
    const mResponse = { name: 'UT' };
    let observer;
    csv()
      .fromStream()
      .subscribe.mockImplementationOnce(onSuccess => {
        observer = onSuccess;
      });
    request.get.mockResolvedValueOnce(mResponse);
    getApiData('http://test.com');
    const mJSON = {};
    expect(observer(mJSON)).toEqual({});
    expect(request.get).toBeCalledWith('http://test.com');
    expect(csv).toHaveBeenCalled();
    expect(csv().fromStream).toBeCalledWith(expect.any(Object));
    done();
  });
});

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

PASS  src/stackoverflow/58842143/api.test.js (10.249s)
  getApiData
    ✓ csv (8ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 api.js   |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.139s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58842143