[英]Jest mock window object before importing a dependency
在導入依賴項之前,我需要在 window object 中設置一個值。 說我有這個代碼
// foo.test.js
import { dependency } from './foo'
describe('...', () => {
it('...', () => {
// use dependency
})
})
但是要導入依賴項,我需要在window.myValues
中定義一個值
// foo.js
export const dependency = {
key: window.myValue.nestedValue
}
該代碼在導入文件時會給我一個錯誤,因為window.myValue.nestedValue
正在嘗試訪問未定義的屬性nestedValue
。
我怎樣才能做到這一點?
編輯以下christianeide 的回答,我收到以下錯誤
● Test suite failed to run
TypeError: Cannot convert undefined or null to object
2 | delete global.window.myValue
3 | global.window = Object.create(window)
> 4 | global.window.myValue = {
| ^
5 | nestedValue: 'someValue'
6 | }
7 | }
at module.exports (jest.setup.js:4:17)
at node_modules/@jest/core/build/runGlobalHook.js:82:17
at ScriptTransformer.requireAndTranspileModule (node_modules/@jest/transform/build/ScriptTransformer.js:684:24)
at node_modules/@jest/core/build/runGlobalHook.js:72:27
at pEachSeries (node_modules/p-each-series/index.js:8:9)
at async _default (node_modules/@jest/core/build/runGlobalHook.js:58:5)
at async runJest (node_modules/@jest/core/build/runJest.js:345:5)
es6 導入是“提升的”,這意味着無論您在代碼中何處編寫它們,它們都會在導入模塊執行之前得到處理,因此導入的模塊總是在導入模塊之前執行。 在您的情況下,這意味着 foo.js 在 foo.test.js 之前執行,因此即使您在測試中正確模擬了window
的屬性,foo.js 也不會看到您的模擬。
在模擬window
的屬性后,您可以通過在測試中使用 require 來導入 foo.js 來解決此問題。
// foo.test.js
window.myValue = { nestedValue: MOCK_NESTED_VALUE };
const { dependency } = require('./foo');
describe('...', () => {
it('...', () => {
// use dependency
})
})
正如其他答案所指出的,如果myValue
是 window 的現有“系統”屬性之一,例如window
,您可能必須window.location
其刪除。 刪除的時候不要忘記備份,以便測試后清理時可以恢復。
嘗試將值分配給global.window
。
像這樣的東西:
delete global.window.myValue;
global.window = Object.create(window);
global.window.myValue = {
nestedValue: 'someValue',
};
這可以在jest.setup.js
中完成,但您也可以在foo.test.js
中定義值
通過創建setup.js
,我能夠在 window object 上的 append 屬性:
global.propertyA = () => {};
global.nestedPropertyB = {
propertyC: () => {}
};
並在我的jest.config.js
文件中的setupFilesAfterEnv
中設置文件:
module.exports = {
setupFilesAfterEnv: ['<rootDir>/tests/js/setup.js']
}
我已經用jest.mock
解決了這樣的問題:因為它被提升到 import 語句之上,所以可以在導入實際模塊之前和之后執行任何代碼。
在我的情況下,我需要測試一些功能並將節點 env 設置為一個不同於“test”的值,並且由於我只需要在導入時進行此替換,因此我在返回實際值之前將其值設置回“test”模塊。 當然,它可能會因用例而異——這只是在導入完成之前和之后執行代碼的示例。 我還嘗試對特定模塊字段使用吸氣劑,它也有效。
import ApiBase from "../ApiBase";
jest.mock('../ApiBase', () => {
process.env.NODE_ENV = '';
const actual = jest.requireActual('../ApiBase');
process.env.NODE_ENV = 'test';
return actual;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.