Reputation: 7372
I'm trying to migrate from AVA to Jest. In AVA you can set ava.setup
, in which you set the jsdom
environment. For example, creating the DOM structure and doing necessary polyfills (localStorage).
How do I accomplish that in Jest? Currently, I'm using beforeEach
in each test suite, which doesn't feel like the best solution.
Upvotes: 25
Views: 45342
Reputation: 543
Update 2022. Version 28 does not ship jsdom by default anymore:
As of Jest 28 "jsdom" is no longer shipped by default, make sure to install it separately.
You'll need to install jsdom manually:
# npm
npm install -D jest-environment-jsdom
# yarn
yarn add -D jest-environment-jsdom
credit to: https://stackoverflow.com/a/72013609/7089048
Upvotes: 15
Reputation: 56935
Here's a complete, minimal example.
package.json
:
{
"scripts": {
"test": "jest"
},
"devDependencies": {
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0"
}
}
jest.config.js
:
module.exports = {
testEnvironment: "jsdom",
setupFilesAfterEnv: ["<rootDir>/setup.js"],
};
setup.js
:
Object.defineProperty(global, "localStorage", {
value: {
getItem: jest.fn().mockReturnValue("hello world!")
},
writable: true
});
hello.js
:
const hello = () => {
document.body.textContent = localStorage.getItem("foo");
};
module.exports = {hello};
__tests__/hello.test.js
:
const {hello} = require("../hello");
it("should say 'hello world'", () => {
hello();
expect(document.body.textContent).toBe("hello world!");
});
Output from npx jest
or npm run test
:
PASS __tests__/hello.test.js
✓ should say 'hello world' (2 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.303 s, estimated 1 s
Ran all test suites.
That said, you may not need to do anything in terms of mocking or polyfills, since localStorage
works out of the box in JSDOM. Removing the setup
code and using a non-mocked localStorage
passes the test as well:
const hello = () => {
localStorage.setItem("foo", "hello world!");
document.body.textContent = localStorage.getItem("foo");
};
module.exports = {hello};
Upvotes: 1
Reputation: 21667
Great question.
Jest actually ships with jsdom
and the environment already configured. You can override it with the testEnvironment
setting.
If you need to set up more aspects of the environment though, you can use the setupTestFrameworkScriptFile
setting to point to a file that executes before all of your tests run.
For example, if you need window.yourVar
to be available on the window for all your tests, you would add this to your package.json
:
"jest": {
"setupTestFrameworkScriptFile": "tests/setup.js"
}
And in tests/setup.js:
Object.defineProperty(window, 'yourVar', { value: 'yourValue' });
Upvotes: 42