request-promise: Problem with request-promise and request-promise-native in Jest

I have recently found that request-promise and request-promise-native can’t be required at the same time in Jest. The reason is that Jest messes up with the require.cache implementation badly enough that stealthy-require is not able to return a fresh instance of request.

The second require will fail with the error

  ● Test suite failed to run

    Unable to expose method "then"

It is quite a problem because both are just indirect dependencies of many projects, so it creates weird incompatibilities.

Can we get rid of the stealthy-require magic and get a different request instance in a different way, to play nicely with Jest module system? For example, could we expose a clone() method to clone request and its prototype instead?

This affects at least to request-promise, request-promise-native and request-promise-any.

I have prepared a minimal repository to reproduce the problem: https://github.com/davazp/request-promise-issue

If needed, I can work on a pull request for this.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 36
  • Comments: 22

Commits related to this issue

Most upvoted comments

I encountered the same problem, and ended with the options of jest jest.json

"setupFiles": [
    "jest.setup.js"
  ]

and use a file jest.setup.js with

jest.mock('request-promise-native');

With the new version of Jest, you should use jest.mock('request-promise-native') instead of jest.mockModule

I’ve published jest-transform-stealthy-require module to address this issue, the README contains usage examples: https://github.com/antonku/jest-transform-stealthy-require

Hope it helps

My Jest tests are always failing because of it…

● Test suite failed to run

    Unable to expose method "then"

Solution @Benno007 does not fit for me because my function does not work at all if I downgrade it.

Thanks for the answer. Finally I resorted to jest.mockModule('request-promise-native').

i can confirm this actually solves things exactly as they are supposed to be solved for us. thank you so much, it saved a lot of headaches on our side. we were stuck working around this very annoying problem for weeks.

@hems I am happy to hear that it worked out well. Thank you very much for the feedback!

Adding just

jest.mock('request-promise-native');

didn’t fix my issue, but adding this did, so maybe it could help someone else too.

jest.mock('request-promise-native', () => ({ options: { request: {} }, }));

I’m also having this problem… while jest.mock('request-promise'); works for one test case, it breaks some other tests that use the request-promise module. Any long term solutions here?

Thanks, fixed it like this :

Screen Shot 2019-07-15 at 10 32 50

I am having the same issue, got a private package using request and request-promise-native and the project depends on request-promise-native it throws the error

 FAIL  lib/async/precommission.test.js
  ● Test suite failed to run

    Unable to expose method "then"

       7 | var _ = require('lodash');
       8 | 
    >  9 | var Update    = require('@privateOrg/update');
         |                 ^
      10 | 
      11 | var dbOptions = {
      12 |   runValidators: true,

      at Object.plumbing.exposePromiseMethod (node_modules/request-promise-core/lib/plumbing.js:140:19)
      at Object.<anonymous>.module.exports (node_modules/request-promise-core/configure/request2.js:57:83)
      at Object.<anonymous> (node_modules/@privateOrg/api/node_modules/request-promise/lib/rp.js:28:1)
      at Object.<anonymous> (node_modules/@privateOrg/api/index.js:4:10)
      at Object.<anonymous> (node_modules/@privateOrg/update/index.js:6:11)
      at Object.require (lib/discovery/handlers/jip/common/index.js:9:17)
      at Object.require (lib/discovery/handlers/jip/fixtures/index.js:9:33)
      at Object.require (lib/discovery/handlers/index.js:4:15)
      at Object.require (lib/models/device.js:6:16)
      at Object.require (lib/async/precommission.js:6:16)
      at Object.require (lib/async/precommission.test.js:1:23)

tried using

jest.mock('request-promise-native');
jest.mock('request-promise');
jest.mock('request-promise-core');

last one throws TypeError: Cannot read property 'exposePromiseMethod' of undefined I am pretty confused and don’t know what to do.

Do you have a temporary solution ?