angular_learner
angular_learner

Reputation: 671

Jest mock not covering function or returning error

I'm trying t write a jest mock test for csvtojson but I'm getting and error:

TypeError: Cannot read property 'subscribe' of undefined

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();
  });
});

then I tested it when if I remove fromStream from my getApiData function it works, but then my coverage shows that json => json has not been called.

I'm really puzzled. Can someone please help?

Upvotes: 1

Views: 4253

Answers (1)

Lin Du
Lin Du

Reputation: 102547

Here is the unit test solution:

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();
  });
});

Unit test result with 100% coverage:

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

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58842143

Upvotes: 2

Related Questions