Create a working chrome.storage and fetch() for your Chrome/edge browser extension during jest
If you need to define a global chrome storage object during Jest runs, you can do that via setupFilesAfterEnv
(See related jest config).
In your jest.config.js
add this line
module.exports = {
...
setupFilesAfterEnv: ['./jest.mocks.js'],
};
And define jest.mocks.js
as follows
let localStorage = {}
let syncStorage = {}
const R = require('ramda');
global.chrome = {
storage: {
local: {
clear: () => {
localStorage = {}
},
set: (toMergeIntoStorage) => {
localStorage = {...localStorage, ...toMergeIntoStorage}
},
get: (keysToInclude) => {
return R.pick(keysToInclude, localStorage);
}
},
sync: {
clear: () => {
syncStorage = {}
},
set: (toMergeIntoStorage) => {
syncStorage = {...syncStorage, ...toMergeIntoStorage}
},
get: (keysToInclude) => {
return R.pick(keysToInclude, syncStorage);
}
}
}
}
Note: you need to add rambda
(yarn add ramda --dev
).
Your tests using chrome storage will now store and return data in memory.
To wipe the content before each test, you can add this into a beforeEach
. See also this test verifying the behaviour.
beforeEach(() => {
chrome.storage.local.clear();
chrome.storage.sync.clear();
});
describe("chrome.storage", () => {
const id = 'id.name';
const dataElements = ['data', 1.2, {a: {b: [1, 2]}}];
for (const data of dataElements) {
it(`local persist + load ${JSON.stringify(data)}`, async () => {
await chrome.storage.local.set({[id]: data});
expect(await chrome.storage.local.get([id])).toEqual({[id]: data});
expect(await chrome.storage.local.get('not existing')).toEqual({});
});
}
for (const data of dataElements) {
it(`local persist + load ${JSON.stringify(data)}`, async () => {
await chrome.storage.local.set({[id]: data});
expect(await chrome.storage.sync.get([id])).toEqual({[id]: data});
expect(await chrome.storage.sync.get('not existing')).toEqual({});
});
}
})
Using a similar approach you can mock functions, like fetch
. If you place this code into the jest.mocks.js
the calls to fetch()
will return the invoking params…
global.fetchLastCallParams = {}
global.fetch = async (url, params) => {
global.fetchLastCallParams = {url, ...params};
return {
status: 200,
json: async () => {
return {
jest: true,
url,
...params
}
}
};
}
So that you can verify the from the jest
test accessing the global variable.
// @ts-ignore
expect(global.fetchLastCallParams).toEqual({
url: "http://S...",
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(...)
});
Note that you can’t override global constants this way. To override a global constant, do the following at the top of your jest
jest.mock("../path/to/file-with-constant", () => ({
__esModule: true,
MY_CONSTANT: "my value"
}))
Correct what I wrote if you know more, I’m a Java backend and I don’t normally do Typescript