jest: `TypeError: Cannot read property 'foo' of undefined` when using es6 imports

Take the following test:

jest.dontMock('../Tracker');

const tracker = require('../Tracker');
const helpers = require('../Helpers');

describe('Tracker', () => {
  describe('functionUnderTest', () => {
    it('should call functionCalledByFunctionUnderTest', () => {
      tracker.functionUnderTest();
      expect(helpers.functionCalledByFunctionUnderTest).toBeCalled();
    });
  });
});

Which tests the following code:

// Tracker.js
import constants from './Constants';
import helpers from './Helpers';

export function functionUnderTest() {
  helpers.functionCalledByFunctionUnderTest();
}

This results in error in Tracker.js: TypeError: Cannot read property 'functionCalledByFunctionUnderTest' of undefined

When I change the es6 imports to require, in Tracker.js, the test passes.

pakage.json includes:

  "jest": {
    "bail": true,
    "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
    "testFileExtensions": [
      "js",
    ],
    "moduleFileExtensions": [
      "js",
    ],
    "testPathDirs": [
      "<rootDir>/src/"
    ],
    "unmockedModulePathPatterns": [
      "node_modules",
    ]
  }

my library versions are:

“jest-cli”: “^12.0.2”, “babel-jest”: “^12.0.2”,

Has anyone seen this before?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 3
  • Comments: 17 (3 by maintainers)

Most upvoted comments

@mike-marcacci this is because of circular dependency in your modules. schema must be imported before X is called, because X imports schema.

@thymikee Shouldn’t there be some kind of circular dependency error here instead of a difficult to understand undefined?

Oh man, you are definitely right… I haven’t run into this while using the es6 import syntax before. I guess the whole static analysis thing made me a bit too comfortable and I let my guard down – I should remind myself that they’re still require() under the hood.

Anyhow, thanks for the help and sorry for the distraction!

@thymikee - thanks for the quick reply! I’ll see if I can distill this down into a minimal repo, but by brute-force trial-and-error, I was able to get this working by explicitly requiring one of the transitive dependencies:

From

import TestHelper from './_TestHelper';

// our test helper
const helper = new TestHelper(__filename);

// variables to be shared between tests
var context, firstIdOnlyResult, firstIdAndTableResult;

// ...

To

import '../schema';
import TestHelper from './_TestHelper';

// our test helper
const helper = new TestHelper(__filename);

// variables to be shared between tests
var context, firstIdOnlyResult, firstIdAndTableResult;

// ...

If I can’t reproduce this in a minimal repo (since it’s likely dependent on the complexity of the dependency tree) I’ll add you as a collaborator to the effected repo.