jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.28k stars 6.47k forks source link

Way to mock Meteor packages? #1388

Closed ffxsam closed 8 years ago

ffxsam commented 8 years ago

I tried the following in a Jest test:

jest.mock('meteor/universe:i18n');

But when my test imports a component using this package, I still get:

 FAIL  __tests__/ArtistTrackUI.js (0s)
● Runtime Error
  - Error: Cannot find module 'meteor/universe:i18n' from 'ArtistTrackUI.js'
        at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:151:17)
        at Object.<anonymous> (__tests__/ArtistTrackUI.js:2:6)

Is there any way I can not only prevent Meteor packages from being imported in Jest tests, but also set up mock functions so the Meteor package functionality (in this case, i18n) will work?

  return <button>{_i18n.__('okBtn')}</button>
cpojer commented 8 years ago

I don't quite understand what :i18n is and it seems like that's why jest.mock fails with the error you are seeing. If you use the correct module name (probably without the :i18n?) it will work.

cpojer commented 8 years ago

Please let me know if :i18n is some sort of webpack thing, though. I have never seen it.

ffxsam commented 8 years ago

It's a Meteor package. So for example, universe:i18n is a Meteor package that can be used via:

import { _i18n } from 'meteor/universe:i18n';

Is there some way in Jest to make it completely ignore all imports that match meteor/* so I can prevent Meteor packages from being loaded, and then just mock them?

cpojer commented 8 years ago

Yeah, I'd recommend to use the moduleNameMapper config option to remap where these direct to: http://facebook.github.io/jest/docs/api.html#modulenamemapper-object-string-string

I don't know how meteor works with module resolution. What does meteor/universe:i18n translate to when using meteor? Which bundler is it using or is meteor its own bundler?

ffxsam commented 8 years ago

I don't know how meteor works with module resolution. What does meteor/universe:i18n translate to when using meteor? Which bundler is it using or is meteor its own bundler?

I wish I could tell you! I'm not clued in to the inner workings of the Meteor build process. It somehow dives into the local package cache and imports those modules.

cpojer commented 8 years ago

I'd recommend going with the moduleNameMapper option to map that module to a stub or something.

ffxsam commented 8 years ago

Does this way make sense? Bear with me, I'm still a Jest n00b. :)

package.json

  "jest": {
    "moduleNameMapper": {
      "^meteor/(.*)": "<rootDir>/__mocks__/meteor/$1.js"
    }

And then I have a __mocks__ folder at root level, and in this case I have:

mocks/meteor/universe:i18n.js

exports._i18n = {
  __: function(value) { return value },
};
// Edited to correct mistake

If there's a more efficient or better way, let me know!

cpojer commented 8 years ago

Yeah, something like this should work.

cpojer commented 8 years ago

It shouldn't be in __mocks__ though, those files are kinda special :)

ffxsam commented 8 years ago

Ah ok, got it. Thanks for your help!

SimonSimCity commented 6 years ago

Just because nobody mentioned it earlier: There is an npm pacakge out there now mocking most of the meteor-internal packages: https://www.npmjs.com/package/jest-meteor-stubs

clemenspeters commented 4 years ago

The following is working for me:

jest.mock('meteor/universe:i18n', () => ({
  getLocale: jest.fn(() => 'de-DE'),
  __: jest.fn(input => {
    switch (input) {
      case 'common.MyKey':
        return 'my translated value';
    }
  })
}));
github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.