Búsqueda de sitios web

angular - No puedo configurar jest correctamente para importar módulos (setupFilesAfterEnv)


Estoy utilizando @angular-builders/jest para reemplazar karma por jest al probar proyectos de Angular. Hay 2 bibliotecas para las que me gustaría obtener matchers adicionales para jest: jest-extended y @testing-library/jest-dom.

No puedo encontrar una manera de importar automáticamente los comparadores para no tener que importarlos en cada archivo de especificación.

ejemplo mínimo para reproducir el problema con jest-extended

Primero, crea un proyecto Angular e instala las dependencias de Jest

ng new --defaults my-project
cd my-project
yarn add -D jest @types/jest @angular-builders/jest jest-extended

Luego edita angular.json para reemplazar el constructor

...
"test": {
    "builder": "@angular-builders/jest:run"
},

Hasta ahora, puedo ejecutar y aprobar las pruebas usando jest con el comando

ng test

Ahora agrego una prueba usando uno de los matchers de jest-extended. En app.component.spec.ts:

...
  it('should work with jest-extended matchers', () => {
    expect([1, 1, 1]).toBeArrayOfSize(3);
  });

Intento #1

crear jest.config.js

module.exports = {
  setupFilesAfterEnv: [
    'jest-extended',
  ],
};

No funciona, obtengo el error TS2339: La propiedad 'toBeArrayOfSize' no existe en el tipo 'ArrayLikeMatchers<number>'

Intento #2

utiliza un archivo de configuración intermedio; crea jest.config.js

module.exports = {
  setupFilesAfterEnv: [
    'my-jest-setup.ts',
  ],
};

con my-jest-setup.ts

import 'jest-extended'

¡Funciona! La prueba pasa... PERO en cuanto cambio algo en mi archivo de especificaciones

...
  it('should work with jest-extended matchers', () => {
    expect([1, 1, 1]).toBeArrayOfSize(3);
    expect(true).toBeTruthy();
  });

y ejecuté la prueba de nuevo, obtengo el mismo error que en el intento #1. Sospecho un problema de caché

Solución alternativa

Usa el intento #2 y limpia la caché de jest antes de cada ejecución con

ng test --clearCache && ng test

No me gusta esta solución porque la caché está destinada a acelerar las cosas y borrar la caché cada vez tiene un impacto sensible cuando hay muchos archivos de especificación. Además, no creo que sea posible borrar la caché al usar jest en modo watch.

Lo siento, esto fue un poco largo, gracias si lo leíste hasta el final

Respuesta #1

Finalmente encontré lo que considero la solución correcta. Comenzando desde un ejemplo mínimo para reproducir el problema con jest-extended,

  1. crear archivo jest.config.js (El intento 1 finalmente fue un buen comienzo)
module.exports = {
  setupFilesAfterEnv: [
    'jest-extended',
  ],
};
  1. edita tsconfig.spec.json y reemplaza "types": ["jasmine", "node"] por "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"]
}

y voilà. Esto en realidad incluye los archivos de declaración de jest y jest-extended en la compilación. Ahora obtengo todos los beneficios de las comprobaciones de tipo de TypeScript y las mejoras de velocidad del caché (excepto en la primera ejecución, obviamente).

Espero que esto ayude

Respuesta #2

Creo que encontré una solución😎. El truco es simplemente habilitar una opción de ts-jest en jest.config.js

module.exports = {
  setupFilesAfterEnv: ['jest-extended'],
  globals: {
    'ts-jest': {
      isolatedModules: true,
    },
  },
};

Debo admitir que no entiendo el objetivo de esta opción, por lo tanto, cualquier aclaración será muy apreciada.

Como ventaja, la ejecución de las pruebas es mucho más rápida.

No hay inconvenientes aparentes hasta ahora, pero te avisaré si sucede algo extraño.

Espero que esto ayude

Editar: la desventaja real es que perdemos la verificación de tipos cuando ts-jest compila para ejecutar las pruebas. El objetivo de la opción isolatedModules se explica en la documentación de ts-jest