Saya menggunakan cuplikan dari #1960 untuk mengejek Picker
di RN
import React, {Component} from 'react';
jest.mock(`Picker`, () => {
// ...etc
});
Bekerja dengan baik di Jest 17, melempar kesalahan berikut di Jest 18:
/Users/simonsmith/Sites/new-look/newlookapp/test/unit/setup.js: babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: React
Whitelisted objects: Array, ArrayBuffer, ..... etc
Saya menggunakan React 15.4.2 dan RN 0.40
Saya mencoba babel-jest@test
dan mereka berjalan seperti yang diharapkan tetapi semua snapshot saya gagal, sepertinya lebih banyak alat peraga datang yang mungkin tidak terkait dengan ini.
Adakah yang bisa saya lakukan untuk memperbaikinya sekarang atau haruskah saya menunggu rilis berikutnya untuk babel-jest
?
Terima kasih :)
Anda perlu melakukan ini:
jest.mock(`Picker`, () => {
const React = require('react');
});
Ini dulunya adalah bug yang kami perbaiki. Dalam tiruan Anda hanya dapat meminta hal-hal secara lokal dan Anda tidak diizinkan untuk mengakses variabel eksternal.
Untuk menjelaskan alasannya: Dengan jest.resetModules()
Anda dapat mengatur ulang semua modul yang tersedia saat ini, jadi ketika Anda memanggil require, Anda akan mendapatkan versi baru dari setiap modul. Jika Anda menggunakan React dari tingkat atas, Anda akan berpotensi memiliki dua salinan React.
Ah ha, itu sedikit yang tidak bisa saya permasalahkan. Terima kasih!
Penggunaan yang satu ini baik-baik saja dan ada pintu keluar untuk itu. Panggil variabel Anda mockFoo
.
Tetapi, Jika saya memiliki banyak ejekan:
jest.mock('./OfferList', () => 'OfferList');
jest.mock('./OfferHeader', () => 'OfferHeader');
jest.mock('./OfferHiredModal', () => 'OfferHiredModal');
Apakah saya harus memasukkan const React = require('React');
di setiap tiruan?
Ya.
jest.mock(`Picker`, () => {
const React = require('React');
});
jika ada yang menyalin tempel ini dan melihatnya gagal di CI (lingkaran/gitlab) dan bukan lokal mereka, pastikan React
adalah huruf kecil react
jest.mock(`Picker`, () => {
const React = require('react');
});
@cpojer Saya ingin menggunakan variabel __dirname
juga tidak diperbolehkan, bagaimana saya bisa mendapatkannya?
Saya tidak ingin menggunakan jalur yang melibatkan lingkungan, seperti /Users/xx/project
@cpojer Saya tidak begitu mengerti penjelasan Anda:
Jika Anda menggunakan React dari tingkat atas, Anda akan berpotensi memiliki dua salinan React.
Jika saya memerlukan React lokal, saya juga akan memiliki dua salinan React lokal, bukan?
Hanya jika Anda menelepon jest.resetModules()
di antara keduanya memerlukan panggilan.
Bagaimana Anda membuatnya berfungsi dengan modul ES6, yang tidak dapat dimasukkan ke dalam lingkup fungsi?
anda dapat menggunakan fungsi import
, bersama dengan misalnya https://github.com/airbnb/babel-plugin-dynamic-import-node
@SimenB Terima kasih... dapatkah anda memberikan contoh? Saya menggunakan TypeScript yang mendukung impor dinamis tetapi saya tidak jelas bagaimana ini akan bekerja karena kemudian implementasi tiruan menjadi asinkron, apakah Jest tahu bagaimana menunggu tiruan diselesaikan sebelum melanjutkan dengan kasus uji?
Tunggu saja janjinya.
let myDep;
beforeEach(async () => {
jest.resetModules();
myDep = await import('./some-modules.js');
})
Tidak tahu bagaimana tampilannya dengan TypeScript, tetapi seharusnya tidak terlalu berbeda
Saya mengalami masalah mengejek dengan fungsi menggunakan sintaks ES6 di dalam contoh:
/**
* @jest-environment jsdom
*/
import SagaTester from "redux-saga-tester";
import supportRequests from "sagas/support_requests";
import reducers from "reducers";
import { fetched } from "actions/support_requests";
describe("success", () => {
it("sends the message via connection", async () => {
const sagaTester = new SagaTester({
reducers: reducers,
initialState: {
router: { location: { pathname: "/support_requests" } },
supportRequests: null,
authenticated: true,
currentUser: { isSupportAgent: true },
},
});
jest.mock("sagas/oauth", () => {
return {
...require.requireActual("sagas/oauth"),
callFetch: function* () {
return { ok: true, json: () => Promise.resolve({ support_requests: [], meta: { pagination: {} } }) };
},
};
});
sagaTester.start(supportRequests);
await sagaTester.waitFor(fetched);
});
});
Operator spread (...) dan fungsi generator diubah oleh babel menjadi sesuatu menggunakan _extends
dan regeneratorRuntime
yang tidak dapat diakses:
babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: _extends
Whitelisted objects: Array, ArrayBuffer, Boolean, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, Generator, GeneratorFunction, Infinity, Int16Array, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, String, Symbol, SyntaxError, TypeError, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, arguments, expect, jest, require, undefined, console, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE, global, process, Buffer, clearImmediate, clearInterval, clearTimeout, setImmediate, setInterval, setTimeout.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` are permitted.
Adakah yang pernah mengalami masalah ini sebelumnya? Saya menggunakan lelucon terbaru.
Mendapatkan kesalahan yang sama tetapi dengan:
Invalid variable access: _asyncToGenerator
Saya menggunakan babel-plugin-transform-regenerator. Bagaimana saya bisa bercanda untuk tidak mengeluh tentang "Pabrik modul jest.mock()
" tidak "diizinkan untuk mereferensikan variabel di luar cakupan" dalam kasus ini?!
// edit:
Tes penuh adalah
it('should request data via API', async () => {
const store = mockStore({ fields: initialState });
jest.resetModules();
jest.mock('services/api-client', () => ({
getFieldsByFarm: async () => {
return [{ field: {} }];
},
}));
const Actions = require('./actions');
const expected = [
{ type: 'FIELDS/REQUEST' },
{ type: 'FIELDS/RECEIVE', payload: { items: [{ field: {} }], didInvalidate: false },},
];
await store.dispatch(Actions.getFieldsByFarm());
const dispatchedActions = store.getActions();
expect(dispatchedActions[0]).toEqual(expected[0]);
expect(dispatchedActions[1].payload).toEqual(expect.objectContaining(expected[1].payload));
});
Membungkus beberapa bagian tes dalam IIFE asinkron dan menghapus async
di depan fungsi tes membuat lelucon tidak membuang kesalahan:
it('should request data via API', (done) => {
const store = mockStore({ fields: initialState });
jest.resetModules();
jest.mock('services/api-clients/nana', () => ({
getFieldsByFarm: async () => {
return [{ field: {} }];
},
}));
const Actions = require('./actions');
(async () => {
const expected = [
{ type: 'FIELDS/REQUEST' },
{
type: 'FIELDS/RECEIVE',
payload: { items: [{ field: {} }], didInvalidate: false },
},
];
await store.dispatch(Actions.getFieldsByFarm());
const dispatchedActions = store.getActions();
expect(dispatchedActions[0]).toEqual(expected[0]);
expect(dispatchedActions[1].payload).toEqual(expect.objectContaining(expected[1].payload));
done();
})();
});
Menggunakan jest.doMock
alih-alih jest.mock
telah membantu saya.
Belum sepenuhnya yakin karena ada hal lain yang gagal sekarang ( ) tetapi sepertinya itu sangat membantu, ya. Terima kasih! 🙂.
Adakah yang tahu mengapa doMock
berhasil dan mock
tidak? Sedikit aneh bagi saya juga bahwa jika saya meletakkan variabel dengan nama "MockedComponent" saya menerima kesalahan, tetapi ketika saya meletakkan "mockedComponent" tidak ada kesalahan, tetapi referensi "tidak terdefinisi".
Panggilan 'jest.mock' dipindahkan dari panggilan 'itu' ke penutupan luar oleh preprosesor dan itu tidak berfungsi dengan baik. Panggilan 'jest.doMock' tidak terpengaruh oleh praprosesor.
Saya menemui masalah ini ketika saya menjalankan lelucon dengan nodejs 10.0.0
, hanya versi simpul yang diturunkan berfungsi.
@Soontao Saya tidak dapat mereproduksi itu, apakah Anda dapat mengatur reproduksi kecil?
@SimenB
Terima kasih atas balasan Anda yang cepat, tetapi ketika saya mencoba mereproduksinya dengan node v10
, saya menemukan bahwa semua tes berfungsi dengan baik, saya pikir masalahnya mungkin disebabkan oleh alasan lain, dan saya kehilangannya ketika saya menginstal ulang nodejs.
Masalah yang sama saat dijalankan dengan nodejs 10.0.0
/xxx/node_modules/react-native/jest/setup.js: babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: console
Whitelisted objects: Array, ArrayBuffer, Boolean, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, Generator, GeneratorFunction, Infinity, Int16Array, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, String, Symbol, SyntaxError, TypeError, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, arguments, expect, jest, require, undefined, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE, global, process, Buffer, clearImmediate, clearInterval, clearTimeout, setImmediate, setInterval, setTimeout.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` are permitted.
at invariant (node_modules/babel-plugin-jest-hoist/build/index.js:14:11)
at newFn (node_modules/babel-traverse/lib/visitors.js:276:21)
at NodePath._call (node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (node_modules/babel-traverse/lib/context.js:150:16)
Itu tidak ada hubungannya dengan node 10, hanya saja kita tidak memiliki console
dalam daftar putih. PR selamat datang! Kami benar-benar harus menggunakan beberapa modul globals
alih-alih daftar putih manual...
Yang terakhir diperbaiki di sini: #6075
Memutakhirkan babel-jest dengan yarn add --dev babel-jest babel-core regenerator-runtime
memperbaiki kesalahan ini untuk saya.
Saya baru saja menemukan ini saat mencari di Google dan sepertinya saya melewatkan baris penting ini dalam pesan kesalahan bersama dengan orang lain:
_Jika dipastikan bahwa mock diperlukan dengan malas, nama variabel yang diawali dengan mock
diperbolehkan._
Ubah saja nama yang Anda olok-olok untuk mengejek YourComponentName
Saya mengalami masalah ini setelah saya menambahkan kode itu di jest.conf saya, untuk menambahkan dukungan tsx dalam pengujian (tanpa kode itu, saya tidak dapat menulis tsx di file spec.tsx saya:
globals: {
jasmine: true,
+ 'ts-jest': {
+ babelConfig: true
+ }
}
module.exports = {
// eslint-disable-next-line no-undef
rootDir: path.resolve(__dirname, '../'),
roots: ['<rootDir>/src'],
verbose: false,
moduleFileExtensions: ['ts', 'tsx', 'vue', 'js', 'jsx', 'json'],
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(ts|js)x?$',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.(js|jsx)?$': 'babel-jest',
'^.+\\.tsx?$': 'ts-jest'
},
transformIgnorePatterns: ['<rootDir>/node_modules/(?!lodash-es)'],
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
setupFilesAfterEnv: ['<rootDir>/test/jest.init.ts'],
// run tests with --coverage to see coverage
coverageDirectory: '<rootDir>/test/coverage',
coverageReporters: ['html', 'text-summary'],
collectCoverageFrom: ['src/**/*.{ts,tsx,js,jsx,vue}', '!**/node_modules/**'],
globals: {
jasmine: true,
'ts-jest': {
babelConfig: true
}
}
}
Kesalahan yang saya dapatkan:
babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: _debounce
Whitelisted objects: Array, ArrayBuffer, Boolean, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, Generator, GeneratorFunction, Infinity, Int16Arra
y, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, String, Symbol, SyntaxEr
ror, TypeError, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, arguments, console, expect, isNaN, jest, parseFloat, parseInt, require, un
defined, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE,
COUNTER_NET_SERVER_CONNECTION, COUNTER_NET_SERVER_CONNECTION_CLOSE, COUNTER_HTTP_SERVER_REQUEST, COUNTER_HTTP_SERVER_RESPONSE, COUNTER_HTTP_CLIENT_REQUEST, COUNTER_HTTP_CLIEN
T_RESPONSE, global, process, Buffer, clearImmediate, clearInterval, clearTimeout, setImmediate, setInterval, setTimeout.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` (case inse
nsitive) are permitted.
Kode itu sendiri:
const DEBOUNCE_DELAY = 10
const _debounce = jest.requireActual('lodash-es/debounce').default
jest.mock('lodash-es/debounce', () =>
jest.fn((fn) => _debounce(fn, DEBOUNCE_DELAY))
)
Saya harus menulis ulang dengan nomor ajaib dan impor sebaris:
jest.mock('lodash-es/debounce', () =>
jest.fn((fn) => jest.requireActual('lodash-es/debounce').default(fn, 10))
)
Perhatikan, bahwa tanpa konfigurasi itu dalam kode globals ( 'ts-jest': { babelConfig: true }
) berfungsi dengan baik. Namun tanpa baris itu di konfigurasi saya tidak dapat menjalankan tes dengan tsx, saya menghadapi kesalahan itu:
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
C:\Users\Alend\vue-project\src\my-component\MyComponent.spec.tsx:20
render: function () { return <div id="foo">Foo</div>; }
^
Beberapa versi dari package.json:
"@babel/core": "^7.4.5",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "24.8.0",
"jest": "24.8.0",
"ts-jest": "24.0.2",
dan konfigurasi babel itu sendiri:
module.exports = {
presets: [
[
'@babel/preset-env',
{
modules: 'commonjs',
targets: {
browsers: ['> 1%', 'last 2 versions', 'not ie <= 11']
}
}
],
'@vue/babel-preset-jsx'
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-json-strings',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
'@babel/plugin-syntax-dynamic-import',
['@babel/plugin-transform-runtime', { corejs: 2 }],
['@babel/plugin-proposal-decorators', { legacy: true }]
]
}
Sepertinya masalah seperti itu masih ada dan sekarang bahkan solusi tidak membantu dalam membuat aplikasi aplikasi reaksi
`
ReferenceError: mockComponent tidak ditentukan
17 | const mockComponent = () => <div>Mock</div>;
18 |
> 19 | jest.mock('./components/Component', () => ({ Component: mockComponent }));
`
@khryshyn
Jest akan secara otomatis mengangkat panggilan jest.mock ke bagian atas modul.
Itu sebabnya const mockComponent
Anda belum ditentukan saat jest.mock dijalankan.
Untuk mengatasi "masalah/fitur" ini, saya melakukannya dalam 2 langkah seperti:
jest.mock('./components/Component', () => ({ Component: jest.fn() }));
import { Component } from "./components/Component";
Component.mockImplementation(() => <div>Mock</div>);
@khryshyn
Jest akan secara otomatis mengangkat panggilan jest.mock ke bagian atas modul.
Itu sebabnya constmockComponent
Anda belum ditentukan saat jest.mock dijalankan.Untuk mengatasi "masalah/fitur" ini, saya melakukannya dalam 2 langkah seperti:
jest.mock('./components/Component', () => ({ Component: jest.fn() })); import { Component } from "./components/Component"; Component.mockImplementation(() => <div>Mock</div>);
Apakah ini benar? Seperti yang sudah disebutkan @nckblu di atas, variabel yang dimulai dengan 'mock' harus tersedia sebagai pengecualian. Dan 'mockComponent' harus termasuk dalam pengecualian itu, bukan?
Sementara itu, jika Anda ingin solusi untuk menambahkan pernyataan debug misalnya console.log('Checking...'), awalan console.log dengan global untuk membuatnya bekerja.
global.console.log('global console working')
Komentar yang paling membantu
Menggunakan
jest.doMock
alih-alihjest.mock
telah membantu saya.