问题
I am using @angular-builders/jest
in order to replace karma by jest when testing angular projects.
There are 2 libraries that I like to get extra matchers for jest: jest-extended
and @testing-library/jest-dom
.
I cannot find a way to import automatically the matchers so that I don't have to import them in each spec file.
minimal example to reproduce the problem with jest-extended
First, create an angular project and install jest dependencies
ng new --defaults my-project
cd my-project
yarn add -D jest @types/jest @angular-builders/jest jest-extended
Then edit angular.json
to replace builder
...
"test": {
"builder": "@angular-builders/jest:run"
},
So far, I can run and pass the tests using jest with command
ng test
Now I add a test using one of the jest-extended matchers. In app.component.spec.ts
:
...
it('should work with jest-extended matchers', () => {
expect([1, 1, 1]).toBeArrayOfSize(3);
});
Attempt #1
create jest.config.js
module.exports = {
setupFilesAfterEnv: [
'jest-extended',
],
};
Does not work, I get error TS2339: Property 'toBeArrayOfSize' does not exist on type 'ArrayLikeMatchers<number>'
Attempt #2
use an intermediate setup file; create jest.config.js
module.exports = {
setupFilesAfterEnv: [
'my-jest-setup.ts',
],
};
with my-jest-setup.ts
import 'jest-extended'
Works! Test passes... BUT as soon as I change something in my spec file
...
it('should work with jest-extended matchers', () => {
expect([1, 1, 1]).toBeArrayOfSize(3);
expect(true).toBeTruthy();
});
and run the test again, I get the same error as in attempt #1. I suspect a cache issue
Workaround
Use attempt #2 and clear jest cache before each run with
ng test --clearCache && ng test
I don't like this solution because the cache is intended to speed up things and clearing the cache each time has a sensitive impact when there are many spec files. Moreover, I don't think it is possible to clear cache when using jest in watch mode
Sorry, this was a bit long, thanks if you read it to the end
回答1:
I think I found a solution😎. The trick is to simply enable a ts-jest
option in jest.config.js
module.exports = {
setupFilesAfterEnv: ['jest-extended'],
globals: {
'ts-jest': {
isolatedModules: true,
},
},
};
I have to admit that I don't understand the goal of this option, hence, any enlightenment will be highly appreciated.
As a bonus, test execution is way faster.
No apparent drawback so far, but I let you know if strange things happen.
I hope this helps
Edit: the actual drawback is that we loose type checking when ts-jest compiles for running the tests. The goal of the isolatedModules
option is explained in ts-jest documentation
回答2:
I finally found what I believe the right solution. Starting from minimal example to reproduce the problem with jest-extended,
- create
jest.config.js
file (Attempt 1 was finally a good start)
module.exports = {
setupFilesAfterEnv: [
'jest-extended',
],
};
- edit
tsconfig.spec.json
and replace"types": ["jasmine", "node"]
by"types": ["jest", "node", "jest-extended"]
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": ["jest", "node", "jest-extended"] // <==== what was missing
},
"files": ["src/test.ts", "src/polyfills.ts"],
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}
and voilà. This will actually includes jest
and jest-extended
declaration files in compilation. I now get all the benefits of TypeScript type checkings and the speed improvements of the cache (except for first run, obviously).
I hope this helps
来源:https://stackoverflow.com/questions/57442151/i-cannot-configure-jest-properly-to-import-modules-setupfilesafterenv