Jest: Jest لا يعمل مع JSX الذي يستورد CSS

تم إنشاؤها على ٧ مارس ٢٠١٧  ·  24تعليقات  ·  مصدر: facebook/jest

هل تريد طلب ميزة أو الإبلاغ عن خطأ ؟
حشرة

ما هو السلوك الحالي؟
إذا كان app.jsx لديك import './app.css'; فمن المستحيل تشغيل الاختبار ، فقد تلقيت هذا الخطأ:

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.

ما هو السلوك المتوقع؟
لإجراء الاختبارات بدون أخطاء ...

يرجى تقديم تكوين Jest الدقيق الخاص بك وذكر إصدار Jest والعقدة والغزل / npm ونظام التشغيل لديك.

نظام التشغيل: Linux Ubuntu 16.04
دعابة: الأحدث
الغزل: الأحدث
العقدة: الأحدث
babel-jest : الأحدث

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

jest: NODE_ENV = مزاح العميل -u

ملاحظة: كل شيء يعمل بشكل جيد إذا قمت بالتعليق / إزالة import './app.css';

التعليق الأكثر فائدة

لقد قمت بحل هذا باستخدام المفتاح moduleNameMapper في تكوينات jest في ملف package.json

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

بعد ذلك ستحتاج إلى إنشاء الملفين كما هو موضح أدناه

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

إذا كنت تستخدم CSS Modules ، فمن الأفضل أن تسخر من وكيل لتمكين عمليات البحث عن className.
ومن ثم ستتغير التكوينات الخاصة بك إلى:

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

لكنك ستحتاج إلى تثبيت حزمة identity-obj-proxy كإدارة تابعة أي

yarn add identity-obj-proxy -D

للمزيد من المعلومات. يمكنك الرجوع إلى مستندات الدعابة

ال 24 كومينتر

maximderbin شكرا!

maximderbin شكرا لك! تم حل مشكلتي عن طريق إضافة moduleNameMapper

svipben @ maximderbinsimonxl أين يجب علي إضافة هذه الوحدة النمطيةNameMapper؟
أرى في المستند أننا سنضيفه في packag.json ولكن أيهما؟
tnx

sarahmarciano moduleNameMapper جزء من التكوين الخاص بك. بشكل افتراضي ، يمكنك تعيين التكوين في package.json (الذي يتميز بمزاح في التبعيات) تحت مفتاح "jest" ، مثل هذا:

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

لقد قمت بحل هذا باستخدام المفتاح moduleNameMapper في تكوينات jest في ملف package.json

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

بعد ذلك ستحتاج إلى إنشاء الملفين كما هو موضح أدناه

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

إذا كنت تستخدم CSS Modules ، فمن الأفضل أن تسخر من وكيل لتمكين عمليات البحث عن className.
ومن ثم ستتغير التكوينات الخاصة بك إلى:

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

لكنك ستحتاج إلى تثبيت حزمة identity-obj-proxy كإدارة تابعة أي

yarn add identity-obj-proxy -D

للمزيد من المعلومات. يمكنك الرجوع إلى مستندات الدعابة

لاحظ أن الأساليب الموصى بها هنا لن تعمل إذا كانت وحدات CSS النمطية الخاصة بك تصدر القيم التي تعتمد عليها ملفات JSX. تفترض معظم الأدلة أنك تستخدم وحدات CSS لتصدير أسماء الفئات فقط. أتمنى أن يكون هناك دليل للاستهزاء بشكل صحيح بوحدات CSS.

@ ماثيو دين ماذا تقصد "الاستهزاء بشكل صحيح بوحدات CSS"؟ هل يمكنك وصف حالة الاستخدام الخاصة بك أكثر قليلاً؟ لدي خبرة كبيرة في استخدام 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}} />
}

هذا مثال مفتعل ، يوضح فقط أنه يمكنك مشاركة الثوابت (القيم) بين وحدات CSS النمطية و JS ، وأنه يمكن تعيين العرض الشرطي أو الخاصيات الديناميكية بناءً على القيم.

ولكن مع identity-obj-proxy ، لا يمكن تحويل هذه القيم إلى أعداد صحيحة ، ناهيك عن القيم الفعلية الموجودة. لذلك إذا كان لديك رمز JSX يعتمد على الثوابت المحددة في وحدات CSS النمطية الخاصة بك ، فلا يمكنك اختبار ذلك دون الاستهزاء بشكل صحيح بوحدة CSS (إعادة كائن يحتوي على القيم كأعداد صحيحة قابلة للاختبار). يفترض identity-obj-proxy فقط أن وحدات CSS الخاصة بك تحتوي على كائن ليس أكثر من أسماء فئات CSS محددة النطاق ؛ لا يدعم الجانب الآخر من وحدات CSS وهو القدرة على تصدير القيم / الثوابت التي يتم استخدامها بدورها في عمليات JS.

تضمين التغريدة

بالمناسبة ، كنت قادرًا على السخرية من وحدة CSS بنجاح مثل هذا:

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

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

آمل أن يكون هذا مفيدًا لشخص آخر يستخدم جميع ميزات وحدات CSS ، ومثلي ، كان يمزق شعره على الإطلاق وفقًا للنصيحة الافتراضية "فقط استخدم identity-obj-proxy ".

لقد قمت بحل هذه المشكلة باستخدام "jest-transform-css".
بعد التثبيت ، تمت إضافة ما يلي في ملف التكوين jest.

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

الآن سيتم نقل ملفات css تمامًا كما فعلت ملفات js.

@ Matthew-dean أين كتبت وحدة CSS الوهمية وكيف تشيرها إلى الدعابة؟

أنا أستخدم حزمة خارجية وتقوم باستيراد ملفاتها الخاصة إلى ملف واحد باستخدام ما يلي:
<strong i="6">@import</strong> "progress-tracker/progress-tracker-variables.scss";

كلما قمت بتشغيل Jest لبدء الاختبار
image
يظهر الخطأ أعلاه. لقد قمت بالفعل بتحديد نموذج css بالحجم الطبيعي داخل package.json
image

أنا أتطلع إلى الحصول على بعض المساعدة حول هذه المسألة. أي حيل ، اقتراحات؟

تحرير: لقد جربت كلاً من حزم babel-jest و Identity-obj-proxy ولم ينجح أي منها. المشكلة لا تزال قائمة.

تحرير 2: لقد جربت أيضًا التكوين أدناه وفقًا للحلول التي صادفتها على الويب.
image

أنا أستخدم Babel 7 ، babel-jest ^24.5.0 ، Jest ^24.1.0 .

بعد اتباع النصيحة أعلاه ، ما زلت أتلقى هذا الخطأ عندما أحاول إنشاء وظيفة أو كائن في ملف اختبار Jest (على سبيل المثال ، $ # import Post.test.js ) عند الملف الهدف (على سبيل المثال Post.js يستورد ./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'

وفقًا للمقال المرتبط أعلاه ، هذا في 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"
    }
  },

وفي الدليل الجذر ، لديّ __mocks__/styleMock.js الذي يحتوي على الكود التالي:

module.exports = {};

أخيرًا ، jest.config.js :

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

والذي بدوره يكوّن الإنزيم:

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

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

import Error
أواجه صعوبة في حل نفس المشكلة تقريبًا حيث يحتوي ملف scss الخاص بي على عبارات import . فشل الاختبار في إخبار SyntaxError: رمز مميز غير صالح أو غير متوقع. يمكن للشخص الرجاء مساعدتي؟

لقد اتبعت الحلول المذكورة أعلاه ولكن لا يبدو أن أيًا منها يعمل من أجلي

لقد تمكنت من حل هذا عن طريق إضافة @babel/polyfill كتبعية مطور

نفس هنا @ fthomas82

لقد قمت بحل هذا باستخدام المفتاح moduleNameMapper في تكوينات jest في ملف package.json

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

بعد ذلك ستحتاج إلى إنشاء الملفين كما هو موضح أدناه

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

إذا كنت تستخدم CSS Modules ، فمن الأفضل أن تسخر من وكيل لتمكين عمليات البحث عن className.
ومن ثم ستتغير التكوينات الخاصة بك إلى:

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

لكنك ستحتاج إلى تثبيت حزمة identity-obj-proxy كإدارة تابعة أي

yarn add identity-obj-proxy -D

للمزيد من المعلومات. يمكنك الرجوع إلى مستندات الدعابة

عملت معي. شكرا!!!

لقد قمت بحل هذه المشكلة باستخدام "jest-transform-css".
بعد التثبيت ، تمت إضافة ما يلي في ملف التكوين jest.

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

الآن سيتم نقل ملفات css تمامًا كما فعلت ملفات js.

شكرا يا اخي krajasekhar
إنه يعمل بالنسبة لي 👍

أضفت التكوين المقترح إلى packages.json ، ولكن دون نجاح ، ثم أدركت أن لديّ jest.config.js في الدليل الجذر لمشروعي ، يستخدم Jest ملف التكوين هذا فوق packages.json .

كمرجع هنا هو ملفي 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',
  },
};

لا بد لي من استيراد ملف css خام في التعليمات البرمجية الخاصة بي

import "./cloud.css?raw"

لقد قمت أيضًا بتعديل تهيئة jest
"jest":{ "moduleNameMapper": { "\\.(css|less|scss|sass|css?raw)$": "identity-obj-proxy" },

ما زلت أتلقى خطأ اختبار في سطر الاستيراد. أي فكرة عن كيفية الاستهزاء باستيراد المواد الخام؟

حل import غير متوقع = :)

ثبت المجموعة:
npm i --save-dev identity-obj-proxy

أضف jest.config.js

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

إذا وصل شخص ما إلى هنا:
هذه الوحدة هي الأحدث التي رأيتها: 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' },

أضفت التكوين المقترح إلى packages.json ، ولكن دون نجاح ، ثم أدركت أن لديّ jest.config.js في الدليل الجذر لمشروعي ، يستخدم Jest ملف التكوين هذا فوق packages.json .

كمرجع هنا هو ملفي 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',
  },
};

شكرًا لكل من قدم حلاً وخاصة Shadoow لك! لقد كان نوعًا من المنطق ولكني كنت أفتقد ... سيتم استخدام ملف التكوين على الإعدادات في package.json

باختصار ، بالنسبة للقادمين الجدد ، ما نجح معي هو اتحاد من الحلول المتعددة التي قدمها فريق أحلام المجتمع لدينا:

1) قم بإنشاء ملف jest.config.json

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

2) تثبيت jest-transform-css:

yarn add jest-transform-css -D

3) هكذا يجب أن يبدو ملف jest config الخاص بك بالشكل التالي:

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) قم بتحديث package.json (أولاً ، انقل جميع تكوينات JEST الخاصة بك ، إذا كان لديك بعضها هناك ، إلى ملف تكوين jest الجديد) ، ثم ينتقل السحر هنا:

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

Tks الجميع!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات