Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automocking: true is broken #6127

Open
CapitanRedBeard opened this issue May 3, 2018 · 20 comments
Open

automocking: true is broken #6127

CapitanRedBeard opened this issue May 3, 2018 · 20 comments

Comments

@CapitanRedBeard
Copy link

CapitanRedBeard commented May 3, 2018

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

Running this in my tests:

import { enums } from './index';

describe('test', () => {
  it('should not blow up ', () => {
    expect(true).toEqual(true);
  });
});

Here is what my index.js looks like

//Lots of other imports
...
export const enums = {
  Foo: 'foo',
};
... 
// Lot's of other things

Here is what happens when I run jest:

 FAIL  src/modules/foo/index.spec.js
  ● Test suite failed to run

    TypeError: Cannot read property 'role' of undefined

      29 |               }
      30 |
    > 31 |               return `${foo}/${bar.splice(0, 1)[0]}`;
      32 |             }
      33 |
      34 |             return `${foo}/${bar}`;

      at Object.<anonymous> (src/utils/fooHelper.js:31:31)
      at Object.<anonymous> (src/modules/baz/index.js:58:20)
      at Object.<anonymous> (src/modules/bar/index.js:50:18)
      at Object.<anonymous> (src/modules/foo/index.js:66:13)
      at Object.<anonymous> (src/modules/foo/index.spec.js:3:14)

So given that I can't use automocking: false, I tried setting it to true which gives this error:

 FAIL  src/modules/foo/index.spec.js
  ● Test suite failed to run

    Failed to get mock metadata: /Users/emmettharper/Dev/foo/node_modules/core-js/library/modules/_global.js

    See: http://facebook.github.io/jest/docs/manual-mocks.html#content

      at Runtime._generateMock (node_modules/jest-runtime/build/index.js:498:15)
      at Object.<anonymous> (node_modules/core-js/library/modules/_export.js:1:103)
      at Object.<anonymous> (node_modules/core-js/library/modules/_iter-define.js:3:15)

Setting:

    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/core-js"
    ]

Also just presents another error:

 FAIL  src/modules/bar/components/__tests__/bar.spec.js
  ● Test suite failed to run

    TypeError: Cannot set property 'DEFAULT_TIMEOUT_INTERVAL' of undefined

      at Object.<anonymous>.exports.create (node_modules/jest-jasmine2/build/jasmine/jasmine_light.js:40:31)

And setting unmocking jest-jasmine2 doesn't seem to fix it.

If the current behavior is a bug, please provide the steps to reproduce and
either a repl.it demo through https://repl.it/languages/jest or a minimal
repository on GitHub that we can yarn install and yarn test.

run node scripts/test.js --env=jsdom

What is the expected behavior?

Ideally I could just grab a simple enum from a file with out jest resolving everything (I have a massive app). But if that's too complicated then I would love for automock to work out of the box.

Please provide your exact Jest configuration

// package.json
  "jest": {
    "automock": true,
    "collectCoverageFrom": ["src/**/*.{js,jsx}"],
    "setupFiles": ["<rootDir>/scripts/testPolyfills.js"],
    "setupTestFrameworkScriptFile": "<rootDir>/scripts/setupTests.js",
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.js?(x)",
      "<rootDir>/src/**/?(*.)(spec|test).js?(x)"
    ],
    "testURL": "http://localhost",
    "transform": {
      "^.+\\.jsx$": "babel-jest",
      "^.+\\.js$": "babel-jest",
      "^.+\\.css$": "<rootDir>/scripts/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/scripts/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!(redux-persist|@pivotusventures/vip-ui-components|react-select)/)"
    ],
    "modulePaths": ["<rootDir>/src"],
    "moduleNameMapper": {
      "^react-native$": "react-native-web",
      "^src(.*)$": "<rootDir>/src$1"
    },
    "moduleFileExtensions": ["web.js", "mjs", "js", "json", "web.jsx", "jsx", "node"],
    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/core-js",
      "<rootDir>/node_modules/jest-jasmine2"
    ]
  }


// scripts/setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  removeItem: jest.fn(),
  clear: jest.fn(),
};

global.localStorage = localStorageMock;

configure({ adapter: new Adapter() });


// scripts/testPolyfills.js
'use strict';

if (typeof Promise === 'undefined') {
  // Rejection tracking prevents a common issue where React gets into an
  // inconsistent state due to an error, but it gets swallowed by a Promise,
  // and the user has no idea what causes React's erratic future behavior.
  require('promise/lib/rejection-tracking').enable();
  window.Promise = require('promise/lib/es6-extensions.js');
}

// fetch() polyfill for making API calls.
require('whatwg-fetch');

// Object.assign() is commonly used with React.
// It will use the native implementation if it's present and isn't buggy.
Object.assign = require('object-assign');

// In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet.
require('raf').polyfill(global);


// scripts/test.js
'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({ silent: true });

const jest = require('jest');
const argv = process.argv.slice(2);

// Watch unless on CI or in coverage mode
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
  argv.push('--watch');
}

jest.run(argv);

Run npx envinfo --preset jest in your project directory and paste the
results here

Environment:
  OS: macOS Sierra 10.12.6
  Node: 8.9.4
  Yarn: 1.3.2
  npm: 5.6.0
  Watchman: 4.9.0
  Xcode: Xcode 9.2 Build version 9C40b
  Android Studio: 3.1 AI-173.4697961

Thanks!

@CapitanRedBeard
Copy link
Author

I understand that manually mocking each file is a workaround here:
kriasoft/react-starter-kit#491
and
#678

but I have a massive project and this is not a scalable solution.

@jcrben
Copy link

jcrben commented Jun 11, 2018

Could you create an actual project that someone can pull down and play with to reproduce the problem?

      at Object.<anonymous> (src/utils/fooHelper.js:31:31)
      at Object.<anonymous> (src/modules/baz/index.js:58:20)
      at Object.<anonymous> (src/modules/bar/index.js:50:18)
      at Object.<anonymous> (src/modules/foo/index.js:66:13)
      at Object.<anonymous> (src/modules/foo/index.spec.js:3:14)

Maybe I'm missing something, but can you disclose fooHelper, baz, and bar?

@dpkshrma
Copy link

dpkshrma commented Aug 3, 2018

I got the similar error as well when I set automock: true in jest.config.json:

Failed to get mock metadata: /Users/deepak/example-app/node_modules/process-nextick-args/index.js

    See: http://facebook.github.io/jest/docs/manual-mocks.html#content

      at Runtime._generateMock (node_modules/jest-runtime/build/index.js:498:15)
      at Object.<anonymous> (node_modules/readable-stream/lib/_stream_readable.js:26:11)
      at Object.<anonymous> (node_modules/readable-stream/readable.js:12:30)

I was trying to use this config to avoid calling jest.mock('../../my-module'); in every test file.

@FuzzOli87
Copy link

When I run jest with automock: true I get some issues as well:

  1. Attempting to mock node-rdkafka fails with the error Cannot read property 'errorCodes' of undefined After some investigation, I see that this is the part of the code where it creates the object from the bindings it has with the underlying C library. It's a bit complex so I fixed it by just creating a manual mock.

However,

Now I get the following error:

received value must be a Promise.
    Received: undefined

When I'm running tests. My module returns a named async function which in fact does return a promise. It works fine without having automock turned on.

@DavidLozzi
Copy link

+1

@nikoremi97
Copy link

Had anyone solved this issue?
Thanks.

@dangreenisrael
Copy link

+1

@bhargavshah
Copy link

This is causing a lot of issues for my project. Appreciate if anyone can update here if they find a solution. Cheers! :)

@maxammann
Copy link

I'm having the same problem. Here is another error that can occure:

    TypeError: Cannot read property 'default' of undefined

      at node_modules/react-native/Libraries/vendor/emitter/EventSubscription.js:15:21
      at Object.<anonymous> (node_modules/react-native/Libraries/vendor/emitter/EventSubscription.js:22:2)
      at Object.require (node_modules/react-native/Libraries/vendor/emitter/EmitterSubscription.js:13:27)

Maybe that helps to make this issue better queryable :)

@andresattler
Copy link

+1

@dimaqq
Copy link

dimaqq commented Jul 22, 2020

Perhaps under "automock": true it becomes user's responsibility to unmock those modules that are being tested?

@luckylooke
Copy link

I am getting "TypeError: Cannot read property 'default' of undefined" from node_module which I expect to be automocked.

 FAIL  src/components/BillingProfile.spec.ts
  ● Test suite failed to run

    TypeError: Cannot read property 'default' of undefined

      15 |           class="text-red"
      16 |           clickable
    > 17 |           @click="devfill()"
         |                                     ^
      18 |         >
      19 |           [DEV] autofill
      20 |         </div>

      at Object.<anonymous> (node_modules/quasar/src/components/form/QForm.js:8:16)
      at src/components/BillingProfile.vue:17:37
      at Object.<anonymous> (src/components/BillingProfile.vue:411:3)
      at Object.<anonymous> (src/components/BillingProfile.spec.ts:2:1)

test

import { shallowMount } from '@vue/test-utils';
import BillingProfile from './BillingProfile.vue';

jest.enableAutomock();
jest.unmock('@vue/test-utils');
jest.unmock('./BillingProfile.vue');

const wrapperFactory = (options = {}) => {
  return shallowMount(BillingProfile, {
    mocks: {
      $route: { path: '/' },
      $store: {},
    },
    ...options,
  });
};

describe('BillingProfile', () => {
  it.only('renders a signup form when user is not present', () => {
    const wrapper = wrapperFactory();

    expect(wrapper.find('.message').text()).toEqual(
      'Welcome to the Vue.js cookbook'
    );
  });
});

jest config

module.exports = {
  // preset reference: https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-plugin-unit-jest/presets/default/jest-preset.js
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  testMatch: ['**/*.spec.ts'],
  moduleNameMapper: {
    '^@/types$': '<rootDir>/src/types/index.d',
    '^@env$': '<rootDir>/src/env/env.dev',
  },
  transformIgnorePatterns: ['node_modules/(?!(quasar|quasar/*|@quasar|@quasar/*))'],
};

@danielrod02
Copy link

+1

@chhatch
Copy link

chhatch commented Feb 9, 2021

Having the same issue. Here is the error:

TypeError: Cannot read property 'default' of undefined

      at Object.<anonymous> (node_modules/zen-observable-ts/src/zenObservable.ts:23:10)
      at Object.<anonymous> (node_modules/zen-observable-ts/src/index.ts:1:1)

@govindrai
Copy link

govindrai commented Mar 4, 2021

@cpojer @aaronabramov @SimenB can we shed some light on this issue, please? 😄 When using automock: true, Jest will throw errors on certain node modules. Manually mocking using jest.mock("name_of_node_module") works but requires us to write a bunch of jest.mocks which is not very scalable. Maybe there is a simple fix?

I would expect that automock:true calls jest#mock under the hood for all imported modules, so seems strange why one works over the other.

Here's a super simple example, as requested:

This works when config is { automock: false, testEnvironment: "node" }

const admin = require("firebase-admin");

jest.mock("firebase-admin");

test("hello", () => {
    expect(true).toBe(true);
});

This breaks when { automock:true, testEnvironment: "node" }

const admin = require("firebase-admin");

test("hello", () => {
    expect(true).toBe(true);
});

Error:

FAIL  ./testjest.spec.js
  ● Test suite failed to run

    TypeError: Cannot read property 'message' of undefined

      at Error.get (node_modules/firebase-admin/lib/utils/error.js:64:35)
          at Array.forEach (<anonymous>)
          at Array.forEach (<anonymous>)
          at Array.forEach (<anonymous>)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.778 s, estimated 1 s
Ran all test suites matching /testjest.spec.js/i.

Environment Details

Jest Version: v26.6.3
Node Version: v10.20.1
firebase-admin Node Module Version: v9.5.0

Appreciate your time!

@dddryba
Copy link

dddryba commented Aug 31, 2021

@govindrai
Do you have a solution for this problem?

@john01kpeazu
Copy link

+1

@eliw00d
Copy link

eliw00d commented Aug 28, 2022

The note on the automock config says:

Node modules are automatically mocked when you have a manual mock in place (e.g.: mocks/lodash.js). More info here.

Which is also broken: #12777

So, I think in general automocking has had a lot of regressions.

@edmundsj
Copy link

I am having this issue as well. It happens regardless of whether I set automock: true in jest.config.js, or run jest.enableAutomock() in my files.

Error message for all test suites:

  ● Test suite failed to run

    Failed to get mock metadata: /home/jordan/Documents/axle-mono/frontend/node_modules/lodash/_freeGlobal.js

    See: https://jestjs.io/docs/manual-mocks#content

      at Runtime._generateMock (node_modules/jest-runtime/build/index.js:1901:15)
      at Object.<anonymous> (node_modules/lodash/_root.js:1:100)

I should also not the documentation pointed to by the error message does not work out of the box. I am using TypeScript and jest version 27.5.1 packaged with CRA.

@ebrahimGH
Copy link

I got this error when i enable automock:

● Test suite failed to run

TypeError: Cannot read properties of undefined (reading 'initTestEnvironment')

> 1 | import 'jest-preset-angular/setup-jest';
    | ^

  at Object.<anonymous> (node_modules/jest-preset-angular/setup-jest.js:11:13)
  at Object.<anonymous> (setup-jest.ts:1:1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests