Stretch0
Stretch0

Reputation: 9285

How to mock https.get with Jest

I have a function that calls https.get inside a promise which I want to test with Jest.

The function is like this:

const request = (url) => {

  return new Promise((resolve, reject) => {
    const chunks = [];
    
    https.get(url, (stream) => {
      stream
        .on('data', (chunk) => {
          if( chunk ) {
            chunks.push(JSON.parse(chunk));
          }
        })
        .on('error', (err) => {
          reject(err);
        })
        .on('end', () => {
          const data = doSomething(chunks);
          resolve(data)
        });
    });
    
  })
}

I want to test that when the function resolves on "end" and rejects on "error";

Currently I have a test like this but because .on("end") doesn't get called, the promise never resolves.

describe("request", () => {

  it("Should resolve", async (done) => {
    
    const response = await request("my-url");

    expect(response).toEqual("some-data")
  })

})

How can I mock events like .on("end") to be called and ensure the promise resolves?

Upvotes: 4

Views: 6046

Answers (1)

Daniel
Daniel

Reputation: 2531

You can do something like this.

// ./request.test.js
jest.mock('https', () => ({
  methodToMock: {}
}));

const Stream = require('stream');
const request = require("./request");
const httpsMock = require("https");

describe("request", () => {

  it("Should resolve", async () => {

    var streamStream = new Stream()
    httpsMock.get = jest.fn().mockImplementation((url, cb) => {

      cb(streamStream)

      streamStream.emit('data', 'some');
      streamStream.emit('data', '-');
      streamStream.emit('data', 'data');

      streamStream.emit('end'); // this will trigger the promise resolve
    })

    const response = await request("my-url");

    expect(response).toEqual("some-data");
  })

})
const https = require("https");

const request = (url) => {

    return new Promise((resolve, reject) => {
        const chunks = [];

        https.get(url, (stream) => {
            stream
                .on('data', (chunk) => {
                    if (chunk) {
                        // chunks.push(JSON.parse(chunk));
                        chunks.push(chunk);
                    }
                })
                .on('error', (err) => {
                    reject(err);
                })
                .on('end', () => {
                    // const data = doSomething(chunks);
                    const data = chunks.join('');
                    resolve(data)
                });
        });

    })
}

module.exports = request;

Note that jest.mock('https', ...) need to be called before const request = require("./request"); if you want https to be mocked.

Upvotes: 6

Related Questions