Jest: console.log(this) is 'undefined' in anywhere

Created on 6 Jul 2017  路  7Comments  路  Source: facebook/jest

console.log(this) is 'undefined' in anywhere, such as setupFiles, setupTestFrameworkScriptFile and test files

import _ from 'underscore'

TypeError: Cannot read property '_' of undefined

if I change underscore resource file at end line

}.call(this));

to

}.call(window));

that is work fine.

version info:

    "babel-jest": "^20.0.3",
    "babel-plugin-transform-amd-to-commonjs": "^0.2.2",
    "babel-preset-es2015": "^6.18.0",
    "jest": "^20.0.4"
    "underscore": "^1.8.3"
good first issue

Most helpful comment

I did some digging into this issue, and top-level this is undefined only when using ECMAScript modules, as is being done here with babel-jest and babel-preset-es2015. I think that's the expected behaviour, since global this should be undefined in ESM as per spec (you can see that babel transforms global this directly to undefined when using the es2015 preset).

That explains why loading underscore from node_modules works fine (I assume babel-jest rightly ignores node_modules), but loading it from within a directory in the project results in this === undefined: the underscore.js file is getting transformed. So in this particular instance, adding underscore.js to the .babelrc ignore field would be the correct solution. Babel even lets you configure top-level this if you really need it, so I don't think there are any code changes required in jest for this issue.

All 7 comments

Would you like to file a PR with the fix? :)

I tried to look into this for a bit but fail to understand what exactly the problem is.

I understood from the issue description, that importing (in this case) the underscore library in a file defined in setupFiles or setupTestFrameworkScriptFile does not work. However I could not reproduce that.

Could you elaborate a bit more? Thanks!

I created a case for this issue:
https://github.com/Leonard-Li777/this-is-undefined-in-Jest

"moduleNameMapper": {'^underscore$': 'test/lib/underscore'},
// This is the wrong key of 'this === undefined', if underscore.js from node_modules then work fine

why is this so?

I did some digging into this issue, and top-level this is undefined only when using ECMAScript modules, as is being done here with babel-jest and babel-preset-es2015. I think that's the expected behaviour, since global this should be undefined in ESM as per spec (you can see that babel transforms global this directly to undefined when using the es2015 preset).

That explains why loading underscore from node_modules works fine (I assume babel-jest rightly ignores node_modules), but loading it from within a directory in the project results in this === undefined: the underscore.js file is getting transformed. So in this particular instance, adding underscore.js to the .babelrc ignore field would be the correct solution. Babel even lets you configure top-level this if you really need it, so I don't think there are any code changes required in jest for this issue.

I think @msrose is right.

@msrose you are right. thanks!

A bit late to the discussion, but in case anyone needs it: I wrote a jscodeshift transformation to move every this.foo to thisFoo throughout your tests. Maybe it helps someone. https://gist.github.com/DanielMSchmidt/9e1bc548ab5d8d1a3fadddc2d735f8c2

Was this page helpful?
0 / 5 - 0 ratings