Jest: Jest ne fonctionne pas avec JSX qui importe CSS

Créé le 7 mars 2017  ·  24Commentaires  ·  Source: facebook/jest

Vous souhaitez demander une fonctionnalité ou signaler un bug ?
Bogue

Quel est le comportement actuel ?
Si app.jsx ont import './app.css'; , il est impossible d'exécuter le test, j'ai cette erreur :

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.

Quel est le comportement attendu ?
Pour lancer des tests sans erreur...

Veuillez fournir votre configuration Jest exacte et mentionner votre version Jest, node, yarn/npm et votre système d'exploitation.

Système d'exploitation : Linux Ubuntu 16.04
Plaisanterie : Dernières
Fil : le plus récent
Nœud : le plus récent
babel-jest : Dernières

.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
        },

blague : NODE_ENV=client blague -u

PS Tout fonctionne bien si je commente/supprime import './app.css';

Commentaire le plus utile

J'ai résolu ce problème en utilisant la clé moduleNameMapper dans les configurations de plaisanterie du fichier package.json

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

Après cela, vous devrez créer les deux fichiers comme décrit ci-dessous

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

Si vous utilisez des modules CSS, il est préférable de se moquer d'un proxy pour activer les recherches de className.
par conséquent, vos configurations deviendront :

{
  "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"
    },
  }
}

Mais vous devrez installer le package identity-obj-proxy en tant que dépendance de développement, c'est-à-dire

yarn add identity-obj-proxy -D

Pour plus d'informations. Vous pouvez vous référer aux docs de plaisanterie

Tous les 24 commentaires

@maximderbin Merci !

@maximderbin Merci ! Cela résout mon problème en ajoutant moduleNameMapper

@svipben @maximderbin @simonxl où dois-je ajouter ce moduleNameMapper ?
Je vois dans la doc qu'on va l'ajouter dans le packag.json mais lequel ?
merci

@sarahmarciano moduleNameMapper fait partie de votre configuration. Par défaut, vous pouvez définir la configuration dans package.json (celui qui contient jest dans les dépendances) sous la clé "jest", comme ceci :

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

J'ai résolu ce problème en utilisant la clé moduleNameMapper dans les configurations de plaisanterie du fichier package.json

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

Après cela, vous devrez créer les deux fichiers comme décrit ci-dessous

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

Si vous utilisez des modules CSS, il est préférable de se moquer d'un proxy pour activer les recherches de className.
par conséquent, vos configurations deviendront :

{
  "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"
    },
  }
}

Mais vous devrez installer le package identity-obj-proxy en tant que dépendance de développement, c'est-à-dire

yarn add identity-obj-proxy -D

Pour plus d'informations. Vous pouvez vous référer aux docs de plaisanterie

Notez que les approches recommandées ici ne fonctionneront pas si vos modules CSS exportent des valeurs dont dépendent vos fichiers JSX. La plupart des guides supposent que vous n'utilisez que des modules CSS pour exporter des noms de classe. J'aimerais qu'il y ait un guide pour se moquer correctement des modules CSS.

@matthew-dean que voulez-vous dire par "se moquer correctement des modules CSS" ? Pouvez-vous décrire un peu plus votre cas d'utilisation ? J'ai une grande expérience avec 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}} />
}

Ceci est un exemple artificiel, démontrant simplement que vous pouvez partager des constantes (valeurs) entre les modules CSS et JS, et que le rendu conditionnel ou les accessoires dynamiques peuvent être attribués en fonction des valeurs.

Mais avec identity-obj-proxy , ces valeurs ne peuvent pas être converties en entiers, sans parler des valeurs réelles présentes. Donc, si vous avez du code JSX qui repose sur des constantes définies dans vos modules CSS, vous ne pouvez pas le tester sans vous moquer correctement du module CSS (avoir un objet retourné qui a les valeurs sous forme d'entiers testables). identity-obj-proxy suppose uniquement que vos modules CSS contiennent un objet avec rien de plus que des noms de classe CSS délimités ; il ne prend pas en charge l'autre aspect des modules CSS qui est la possibilité d'exporter des valeurs/constantes qui à leur tour sont utilisées dans les opérations JS.

@SimenB

Incidemment, j'ai pu simuler le module CSS avec succès comme ceci :

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

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

J'espère que c'est utile pour quelqu'un d'autre qui utilise toutes les fonctionnalités des modules CSS et, comme moi, s'arrache les cheveux à tous les conseils par défaut "utilisez simplement identity-obj-proxy ".

J'ai résolu ce problème en utilisant 'jest-transform-css'.
Après l'installation, ajoutez ce qui suit dans la configuration de plaisanterie.

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

Maintenant, les fichiers CSS seront transpilés comme les fichiers js.

@matthew-dean où avez-vous écrit la maquette du module CSS et comment le référencez-vous en plaisantant ?

J'utilise un package externe et il importe ses propres fichiers dans un seul fichier en utilisant ce qui suit :
<strong i="6">@import</strong> "progress-tracker/progress-tracker-variables.scss";

Chaque fois que je lance le Jest pour commencer à tester
image
l'erreur ci-dessus apparaît. J'ai déjà spécifié la maquette css dans le package.json
image

Je suis impatient d'obtenir de l'aide sur ce problème. Des astuces, des suggestions ?

Edit: j'ai essayé les packages babel-jest et identity-obj-proxy et aucun de ceux-ci n'a fonctionné. Le problème persiste toujours.

Edit 2 : J'ai également essayé la configuration ci-dessous en fonction des solutions que j'ai rencontrées sur le Web.
image

J'utilise Babel 7 , babel-jest ^24.5.0 , Jest ^24.1.0 .

Après avoir suivi les conseils ci-dessus, j'obtiens toujours cette erreur lorsque j'essaie de import une fonction ou un objet dans un fichier de test Jest (par exemple Post.test.js ) lorsque le fichier cible (par exemple Post.js ) importe un fichier CSS - par exemple ./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'

Selon l'article lié ci-dessus, c'est dans mon 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"
    }
  },

et dans le répertoire racine, j'ai __mocks__/styleMock.js qui a le code suivant :

module.exports = {};

Enfin, mes jest.config.js :

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

Qui à son tour configure Enzyme :

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

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

import Error
J'ai du mal à résoudre presque le même problème où mon fichier scss contient des instructions @import . Le test échoue en indiquant SyntaxError : jeton non valide ou inattendu. quelqu'un peut m'aider s'il vous plait?

J'ai suivi les solutions données ci-dessus mais aucune d'entre elles ne semble fonctionner pour moi

J'ai pu résoudre ce problème en ajoutant @babel/polyfill en tant que dépendance de développement

pareil ici @ fthomas82

J'ai résolu ce problème en utilisant la clé moduleNameMapper dans les configurations de plaisanterie du fichier package.json

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

Après cela, vous devrez créer les deux fichiers comme décrit ci-dessous

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

Si vous utilisez des modules CSS, il est préférable de se moquer d'un proxy pour activer les recherches de className.
par conséquent, vos configurations deviendront :

{
  "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"
    },
  }
}

Mais vous devrez installer le package identity-obj-proxy en tant que dépendance de développement, c'est-à-dire

yarn add identity-obj-proxy -D

Pour plus d'informations. Vous pouvez vous référer aux docs de plaisanterie

Cela a fonctionné pour moi. Merci!!!

J'ai résolu ce problème en utilisant 'jest-transform-css'.
Après l'installation, ajoutez ce qui suit dans la configuration de plaisanterie.

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

Maintenant, les fichiers CSS seront transpilés comme les fichiers js.

Merci, frère @krajasekhar
Ça marche pour moi 👍

J'ai ajouté la configuration suggérée à packages.json , sans succès, puis j'ai réalisé que j'avais un jest.config.js dans le répertoire racine de mon projet, Jest utilise ce fichier de configuration sur packages.json .

Pour référence, voici mon fichier 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',
  },
};

Je dois importer un css brut dans mon code

import "./cloud.css?raw"

J'ai aussi modifié la configuration de jest
"jest":{ "moduleNameMapper": { "\\.(css|less|scss|sass|css?raw)$": "identity-obj-proxy" },

Pourtant, je reçois une erreur de test sur la ligne d'importation. Une idée de comment se moquer de l'importation brute ?

Solution de @import Jeton inattendu = :)

Installer le paquet:
npm i --save-dev identity-obj-proxy

Ajouter dans jest.config.js

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

Si quelqu'un arrive ici :
Ce module est le plus mis à jour que j'ai vu : 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' },

J'ai ajouté la configuration suggérée à packages.json , sans succès, puis j'ai réalisé que j'avais un jest.config.js dans le répertoire racine de mon projet, Jest utilise ce fichier de configuration sur packages.json .

Pour référence, voici mon fichier 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',
  },
};

Merci à tous ceux qui ont présenté une solution et spécialement à vous @Shadoow ! C'était une sorte de chose logique mais il me manquait ça ... le fichier de configuration sera utilisé sur les paramètres de package.json

En bref, pour les nouveaux arrivants, ce qui a fonctionné pour moi était une union de plusieurs solutions présentées par notre équipe de rêve communautaire :

1) créer un fichier jest.config.json

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

2) Installez jest-transform-css :

yarn add jest-transform-css -D

3) Voici à quoi devrait ressembler votre fichier de configuration 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) Mettez à jour votre package.json (d'abord, transférez toutes vos configurations JEST, si vous en avez, vers le nouveau fichier de configuration jest), puis la magie opère ici :

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

Merci à tous !

Cette page vous a été utile?
0 / 5 - 0 notes