javascript - How to mock a method inside Express router Jest test? - Stack Overflow

I'm trying to test a router in Node.js app with Jest + Supertest, but my router is making a call t

I'm trying to test a router in Node.js app with Jest + Supertest, but my router is making a call to service, which is calling the endpoint:

router.post('/login', async (req, res, next) => {
  try {
    const { username, password } = req.body;

    // I WANT TO MOCK userService.getUserInfo FUNCTION, BECAUSE IT IS MAKING A POST CALL
    const identity = await userService.getUserInfo(username, password);

    if (!identity.authenticated) {
      return res.json({});
    }

    const requiredTenantId = process.env.TENANT_ID;
    const tenant = identity.tenants.find(it => it.id === requiredTenantId);

    if (requiredTenantId && !tenant) {
      return res.json({});
    }

    const userResponse = {
      ...identity,
      token: jwt.sign(identity, envVars.getVar(envVars.variables.AUTH_TOKEN_SECRET), {
        expiresIn: '2h',
      }),
    };

    return res.json(userResponse);
  } catch (err) {
    return next(err);
  }
});

This is my test that works well:

test('Authorized - respond with user object', async () => {
  const response = await request(app)
    .post('/api/user/login')
    .send(users.authorized);
  expect(response.body).toHaveProperty('authenticated', true);
});

this is how getUserInfo function looks like:

const getUserInfo = async (username, password) => {
  const identity = await axios.post('/user', {username, password});

  return identity;
}

but it executes the method getUserInfo inside a router and this method is making a REST call - I want to mock this method in order to avoid REST calls to other services. How it could be done?

I've found a mockImplementation function in Jest docs .html#mockfnmockimplementationfn

but how I can mock func inside a supertest testing?

I'm trying to test a router in Node.js app with Jest + Supertest, but my router is making a call to service, which is calling the endpoint:

router.post('/login', async (req, res, next) => {
  try {
    const { username, password } = req.body;

    // I WANT TO MOCK userService.getUserInfo FUNCTION, BECAUSE IT IS MAKING A POST CALL
    const identity = await userService.getUserInfo(username, password);

    if (!identity.authenticated) {
      return res.json({});
    }

    const requiredTenantId = process.env.TENANT_ID;
    const tenant = identity.tenants.find(it => it.id === requiredTenantId);

    if (requiredTenantId && !tenant) {
      return res.json({});
    }

    const userResponse = {
      ...identity,
      token: jwt.sign(identity, envVars.getVar(envVars.variables.AUTH_TOKEN_SECRET), {
        expiresIn: '2h',
      }),
    };

    return res.json(userResponse);
  } catch (err) {
    return next(err);
  }
});

This is my test that works well:

test('Authorized - respond with user object', async () => {
  const response = await request(app)
    .post('/api/user/login')
    .send(users.authorized);
  expect(response.body).toHaveProperty('authenticated', true);
});

this is how getUserInfo function looks like:

const getUserInfo = async (username, password) => {
  const identity = await axios.post('/user', {username, password});

  return identity;
}

but it executes the method getUserInfo inside a router and this method is making a REST call - I want to mock this method in order to avoid REST calls to other services. How it could be done?

I've found a mockImplementation function in Jest docs https://jestjs.io/docs/en/mock-function-api.html#mockfnmockimplementationfn

but how I can mock func inside a supertest testing?

Share Improve this question edited Apr 2, 2020 at 15:31 Karen asked Apr 2, 2020 at 14:45 KarenKaren 1,4295 gold badges27 silver badges50 bronze badges 7
  • I guess that you start a "real" api server before these tests, that means that your tests are running in a different node context (separate process), therefore there is no why that tests can mock something in it. Am I right? – felixmosh Commented Apr 2, 2020 at 15:16
  • I've added getUserInfo to the description – Karen Commented Apr 2, 2020 at 15:21
  • I want to mock this function in order not to make calls to external API – Karen Commented Apr 2, 2020 at 15:22
  • Is my assumption is correct? you start an API server & run the tests? – felixmosh Commented Apr 2, 2020 at 15:31
  • no, 'API server' is the external service – Karen Commented Apr 2, 2020 at 15:32
 |  Show 2 more ments

1 Answer 1

Reset to default 6

You can use jest's auto mocking at the top of your test

like so:

jest.mock('./path/to/userService');

// and include it as well in your test
const userService = require('./path/to/userService');

it will generate a mock of the entire module and every function will be replaced with jest.fn() with no implementation

and then depending on the userService if it's just an object it's getUserInfo method will be a jest.fn() and you can set it's return value like this:

// resolved value as it should return a promise
userService.getUserInfo.mockResolvedValue(mockIdentity);

and the mockIdentity will have to look something like this:

const mockIdentity = {
      authenticated: true,
      tenants: [
        {
          id: "x12",
          mockInfo: "mock-info-value"
        }
      ],
      mother: "Superwoman",
      father: "Superman"
    })
  }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744852567a4597213.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信