Jest: Jest no funciona con JSX que importa CSS

Creado en 7 mar. 2017  ·  24Comentarios  ·  Fuente: facebook/jest

¿Desea solicitar una característica o informar un error ?
Error

¿Cuál es el comportamiento actual?
Si app.jsx tiene import './app.css'; es imposible ejecutar la prueba, recibí este error:

yarn run:test v0.21.3
$ NODE_ENV=client jest -u
 FAIL  src/__tests__/app.test.js
  ● Test suite failed to run

    /home/svipben/Documents/react-boilerplate/src/client/app/app.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){body {
                                                                                                  ^
    SyntaxError: Unexpected token {

      at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:320:12)
      at Object.<anonymous> (src/client/app/app.jsx:7:1)
      at Object.<anonymous> (src/__tests__/app.test.js:2:12)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.693s
Ran all test suites.
error Command failed with exit code 1.

¿Cuál es el comportamiento esperado?
Para ejecutar pruebas sin error...

Proporcione su configuración exacta de Jest y mencione su Jest, nodo, versión de yarn/npm y sistema operativo.

Sistema operativo: Linux Ubuntu 16.04
Broma: Lo último
Hilo: Lo último
Nodo: Último
babel-jest : Último

.babelrc:

        "client": {
            "presets": [
                "latest", // All you need to compile what's in ES2015+
                "flow", // Flow support
                "react", // Strip flow types and transform JSX
                "stage-2" // Experimental syntax extensions
            ],
            "sourceMaps": true // Compile with Source Maps
        },

broma: NODE_ENV=cliente broma -u

PD Todo funciona bien si comento/elimino import './app.css';

Comentario más útil

Resolví esto usando la tecla moduleNameMapper en las configuraciones de broma en el archivo package.json

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

Después de esto, deberá crear los dos archivos como se describe a continuación.

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

Si está utilizando módulos CSS, es mejor simular un proxy para habilitar las búsquedas de className.
por lo tanto, sus configuraciones cambiarán a:

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

Pero deberá instalar el paquete identity-obj-proxy como una dependencia de desarrollo, es decir

yarn add identity-obj-proxy -D

Para más información. Puede consultar los documentos de broma

Todos 24 comentarios

@maximderbin ¡Gracias!

@maximderbin ¡Gracias! Resuelve mi problema agregando moduleNameMapper

@svipben @maximderbin @simonxl ¿dónde tengo que agregar este moduleNameMapper?
Veo en el documento que lo agregaremos en el paquete.json, pero ¿cuál?
gracias

@sarahmarciano moduleNameMapper es parte de su configuración. De forma predeterminada, puede establecer la configuración en package.json (el que presenta broma en las dependencias) bajo la tecla "broma", así:

{
  "dependencies": {...}
  "jest": {
    "moduleNameMapper": {...}
  }
}

Resolví esto usando la tecla moduleNameMapper en las configuraciones de broma en el archivo package.json

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

Después de esto, deberá crear los dos archivos como se describe a continuación.

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

Si está utilizando módulos CSS, es mejor simular un proxy para habilitar las búsquedas de className.
por lo tanto, sus configuraciones cambiarán a:

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

Pero deberá instalar el paquete identity-obj-proxy como una dependencia de desarrollo, es decir

yarn add identity-obj-proxy -D

Para más información. Puede consultar los documentos de broma

Tenga en cuenta que los enfoques recomendados aquí no funcionarán si sus módulos CSS exportan valores de los que dependen sus archivos JSX. La mayoría de las guías asumen que solo estás usando módulos CSS para exportar nombres de clases. Desearía que hubiera una guía para burlarse adecuadamente de los módulos CSS.

@ matthew-dean, ¿qué quiere decir con "módulos CSS que se burlan correctamente"? ¿Puede describir su caso de uso un poco más? Tengo una gran experiencia usando identity-obj-proxy

:export {
  sizeMobile: $size-mobile / 1px;
  sizePhablet: $size-phablet / 1px;
  sizeSmallTablet: $size-small-tablet / 1px;
  sizeTablet: $size-tablet / 1px;
  sizeDesktop: $size-desktop / 1px;
  sizeLargeDesktop: $size-large-desktop / 1px;
}
import styles from './variables.scss'

const tileSize = parseFloat(styles.sizeTablet) / 3
//...
render() {
  return <Tile style={{width: tileSize}} />
}

Este es un ejemplo artificial, que solo demuestra que puede compartir constantes (valores) entre los módulos CSS y JS, y que la representación condicional o los accesorios dinámicos se pueden asignar en función de los valores.

Pero con identity-obj-proxy , estos valores no se pueden convertir en enteros, y mucho menos los valores reales que están presentes. Entonces, si tiene un código JSX que se basa en constantes definidas en sus módulos CSS, entonces no puede probar esto sin burlarse adecuadamente del módulo CSS (devolviendo un objeto que tiene los valores como enteros comprobables). identity-obj-proxy solo asume que sus módulos CSS contienen un objeto con nada más que nombres de clases CSS con alcance; no es compatible con el otro aspecto de los módulos CSS, que es la capacidad de exportar valores/constantes que, a su vez, se utilizan en las operaciones de JS.

@SimenB

Por cierto, pude simular el módulo CSS con éxito de esta manera:

const styles = require('styles/variables.scss')

jest.mock('styles/variables.scss', () => {
  return {
    sizePhablet: 500,
    sizeSmallTablet: 768,
    sizeTablet: 1024,
    sizeDesktop: 1440,
    sizeLargeDesktop: 1920
  }
})

Con suerte, eso es útil para alguien más que esté usando todas las características de los módulos CSS y, como yo, se estaba arrancando los pelos con todos los consejos predeterminados de "solo use identity-obj-proxy ".

Resolví este problema usando 'jest-transform-css'.
Después de la instalación, agregue lo siguiente en la configuración de broma.

"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

Ahora los archivos css se transpilarán como lo hicieron los archivos js.

@ matthew-dean, ¿dónde escribiste el simulacro del módulo CSS y cómo lo referencias a broma?

Estoy usando un paquete externo e importa sus propios archivos a un solo archivo usando lo siguiente:
<strong i="6">@import</strong> "progress-tracker/progress-tracker-variables.scss";

Cada vez que ejecuto el Jest para comenzar a probar
image
aparece el error anterior. Ya he especificado la maqueta css dentro del paquete.json
image

Estoy deseando obtener ayuda sobre ese problema. ¿Algún truco, sugerencia?

Editar: probé los paquetes babel-jest e Identity-obj-proxy y ninguno de ellos funcionó. El problema aún persiste.

Edición 2: también probé la configuración a continuación de acuerdo con las soluciones que encontré en la web.
image

Estoy usando Babel 7 , babel-jest ^24.5.0 , Jest ^24.1.0 .

Después de seguir el consejo anterior, sigo recibiendo este error cuando intento import una función u objeto en un archivo de prueba de Jest (p. ej Post.test.js ) cuando el archivo de destino (p. ej Post.js ) importa un archivo CSS, por ejemplo, ./postStyles.css .

Jest encountered an unexpected token

SyntaxError: Unexpected token .

Details:

    /Users/ben/Desktop/Work/code/bengrunfeld/src/front-end/components/Post/postStyles.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.post h1, .post h2, .post h3 {

      3 |
      4 | import { PostText } from './styles'
    > 5 | import './postStyles.css'

Según el artículo vinculado anteriormente, esto está en mi package.json :

"jest": {
    "moduleFileExtensions": ["js", "jsx"],
    "moduleDirectories": ["node_modules", "bower_components", "shared"],

    "moduleNameMapper": {
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
      "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js",

      "^react(.*)$": "<rootDir>/vendor/react-master$1",
      "^config$": "<rootDir>/configs/app-config.js"
    }
  },

y en el directorio raíz tengo __mocks__/styleMock.js que tiene el siguiente código:

module.exports = {};

Por último, mi jest.config.js :

module.exports = {
  setupFiles: ['<rootDir>/src/test/setup.js']
}

Que a su vez configura Enzyme:

import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

Enzyme.configure({ adapter: new Adapter() })

import Error
Estoy luchando para resolver casi el mismo problema donde mi archivo scss contiene declaraciones @import . La prueba falla y dice SyntaxError: token no válido o inesperado. ¿Puede alguien ayudarme por favor?

Seguí las soluciones dadas anteriormente, pero ninguna de ellas parece estar funcionando para mí.

Pude resolver esto agregando @babel/polyfill como una dependencia de desarrollo

lo mismo aquí @fthomas82

Resolví esto usando la tecla moduleNameMapper en las configuraciones de broma en el archivo package.json

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

Después de esto, deberá crear los dos archivos como se describe a continuación.

  • __mocks__/styleMock.js
module.exports = {};
  • __mocks__/fileMock.js
module.exports = 'test-file-stub';

Si está utilizando módulos CSS, es mejor simular un proxy para habilitar las búsquedas de className.
por lo tanto, sus configuraciones cambiarán a:

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

Pero deberá instalar el paquete identity-obj-proxy como una dependencia de desarrollo, es decir

yarn add identity-obj-proxy -D

Para más información. Puede consultar los documentos de broma

Funcionó para mí. ¡¡¡Gracias!!!

Resolví este problema usando 'jest-transform-css'.
Después de la instalación, agregue lo siguiente en la configuración de broma.

"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

Ahora los archivos css se transpilarán como lo hicieron los archivos js.

Gracias, hermano @krajasekhar
A mi me funciona 👍

Agregué la configuración sugerida a packages.json , sin éxito, luego me di cuenta de que tenía un jest.config.js en el directorio raíz de mi proyecto, Jest usa ese archivo de configuración en packages.json .

Como referencia, aquí está mi archivo jest.config.js :

module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

Tengo que importar un css sin formato en mi código

import "./cloud.css?raw"

También modifiqué la configuración de broma
"jest":{ "moduleNameMapper": { "\\.(css|less|scss|sass|css?raw)$": "identity-obj-proxy" },

aún así, recibo un error de prueba en la línea de importación. ¿Alguna idea de cómo burlarse de la importación sin procesar?

Solución de @import Token inesperado = :)

Paquete de instalación:
npm i --save-dev identity-obj-proxy

Agregue jest.config.js

module.exports = {
  "moduleNameMapper": {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  }
}

Si alguien llega aquí:
Este módulo es el más actualizado que he visto: https://www.npmjs.com/package/jest-css-modules-transform

transform: { '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest', ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform" }, transformIgnorePatterns: [ '/node_modules/', '^.+\\.module\\.(css|sass|scss)$', ], moduleNameMapper: { '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy' },

Agregué la configuración sugerida a packages.json , sin éxito, luego me di cuenta de que tenía un jest.config.js en el directorio raíz de mi proyecto, Jest usa ese archivo de configuración en packages.json .

Como referencia, aquí está mi archivo jest.config.js :

module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

¡Gracias a todos los que presentaron una solución y especialmente a ti @Shadoow! Era una especie de cosa lógica, pero me faltaba eso ... el archivo de configuración se usará sobre la configuración en package.json

En resumen, para los recién llegados, lo que funcionó para mí fue una unión de múltiples soluciones presentadas por nuestro equipo de ensueño de la comunidad:

1) crear un archivo jest.config.json

touch jest.config.json open jest.config.json

2) Instale jest-transform-css:

yarn add jest-transform-css -D

3) Así es como debería verse el archivo de configuración de jest:

module.exports = {
  preset: 'ts-jest/presets/js-with-babel',
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)$': './jest.mock.js',
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/assets/'],
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '\\.(css|less|scss|sass)$': 'jest-transform-css',
  },
};

4) Actualice su paquete.json (primero, transfiera todas sus configuraciones de JEST, si tiene algunas allí, al nuevo archivo de configuración de jest), luego la magia va aquí:

"test": "jest --config ./jest.config.js"

¡Gracias a todos!

¿Fue útil esta página
0 / 5 - 0 calificaciones