2

I have run into an issue that files and functions cannot be mocked, that is used in a handler of an API call. This call is simulated using superagent.

Here is the code of the test

// users.itest.js
const request = require('superagent');
const get = async url => request
  .get(`${process.env.API_URL}${url}`);

describe('endpoint', () => {
it('GET', async () => {
  jest.mock('../token-store', () => ({
    getToken: jest.fn().mockReturnValue('token'),
  }));

  const { status, body } = await get('/api/users');
  expect(status).toEqual(200);
  expect(body).toHaveValidSchema(userSchema);
});

And here is the handler that is called by the '/api/users' endpoint

const someHandler = async (req, res) => {
  const token = await tokenStore.getToken();

  res.send(token);
};

I tried mocking it like shown, however, I couldn't find a solution. Thanks.

Joao Jorge
  • 103
  • 1
  • 2
  • 16
donatasdev
  • 33
  • 1
  • 4
  • Your code is not completed. Please edit. E.g. where is `api` and what's `someHandler`? Provide minimal completed code you want to test. – Lin Du Dec 20 '19 at 14:46

1 Answers1

0

You should use jest.mock() in the module scope, not function scope.

Here is the integration test solution:

app.js:

const express = require('express');
const tokenStore = require('./token-store');

const app = express();

const someHandler = async (req, res) => {
  const token = await tokenStore.getToken();
  res.send(token);
};

app.get('/api/users', someHandler);

module.exports = app;

token-store.js:

async function getToken() {
  return 'real token';
}

module.exports = {
  getToken,
};

users.test.js:

const request = require('superagent');
const app = require('./app');

const port = 3000;
process.env.API_URL = `http://localhost:${port}`;
const get = async (url) => request.get(`${process.env.API_URL}${url}`);

jest.mock('./token-store', () => ({
  getToken: jest.fn().mockReturnValue('token'),
}));

describe('endpoint', () => {
  let server;
  beforeAll((done) => {
    server = app.listen(port, () => {
      console.info(`HTTP server is listening on http://localhost:${server.address().port}`);
      done();
    });
  });

  afterAll((done) => {
    server.close(done);
  });

  it('GET', async () => {
    const { status, text } = await get('/api/users');
    expect(status).toEqual(200);
    expect(text).toBe('token');
  });
});

Integration test result with coverage report:

 PASS  src/stackoverflow/59426030/users.test.js (10.767s)
  endpoint
    ✓ GET (74ms)

  console.info src/stackoverflow/59426030/users.test.js:16
    HTTP server is listening on http://localhost:3000

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

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

Lin Du
  • 88,126
  • 95
  • 281
  • 483