score:81
this example will work if you compile es6 modules syntax into es5, because in the end, all module exports belong to the same object, which can be modified.
import { allowthrough } from './allowthrough';
import { enabled } from './constants';
import * as constants from './constants';
describe('allowthrough', () => {
test('success', () => {
constants.enabled = true;
expect(enabled).tobe(true);
expect(allowthrough({ value: 1 })).tobe(true);
});
test('fail, enabled === false', () => {
constants.enabled = false;
expect(enabled).tobe(false);
expect(allowthrough({ value: 1 })).tobe(false);
});
});
alternatively, you can switch to raw commonjs require
function, and do it like this with the help of jest.mock(...)
:
const mocktrue = { enabled: true };
const mockfalse = { enabled: false };
describe('allowthrough', () => {
beforeeach(() => {
jest.resetmodules();
});
test('success', () => {
jest.mock('./constants', () => mocktrue)
const { enabled } = require('./constants');
const { allowthrough } = require('./allowthrough');
expect(enabled).tobe(true);
expect(allowthrough({ value: 1 })).tobe(true);
});
test('fail, enabled === false', () => {
jest.mock('./constants', () => mockfalse)
const { enabled } = require('./constants');
const { allowthrough } = require('./allowthrough');
expect(enabled).tobe(false);
expect(allowthrough({ value: 1 })).tobe(false);
});
});
score:-1
i solved this by initializing constants from contstantsfile.js in reducers. and placed it in redux store. as jest.mock was not able to mock the contstantsfile.js
constantsfile.js
-----------------
const my_constants = {
my_constant1: "test",
my_constant2: "best",
};
export defualt my_constants;
reducers/index.js
-----------------
import my_const from "./constantsfile";
const initialstate = {
...my_const
}
export const abcreducer = (state = initialstate, action) => {.....}
abc.jsx
------------
import { useselector } from 'react-redux';
const abc = () => {
const const1 = useselector(state) => state. abcreducer. my_constant1:
const const2 = useselector(state) => state. abcreducer. my_constant2:
.......
now we can easily mock the store in test.jsx and provide the values to constant that we want.
abc.text.jsx
-------------
import thunk from 'redux-thunk';
import configuremockstore from 'redux-mock-store';
describe('abc mock constants in jest', () => {
const mockstore = configuremockstore([thunk]);
let store = mockstore({
abcreducer: {
my_constant1 ="mocktest",
my_constant2 = "mockbest",
}
});
test('your test here', () => { .....
now when the test runs it will always pick the constant value form mock store.
score:1
instead of jest and having trouble with hoisting etc. you can also just redefine your property using "object.defineproperty"
it can easily be redefined for each test case.
this is a pseudo code example based on some files i have:
from localization file:
export const locale = 'en-us';
in another file we are using the locale:
import { locale } from 'src/common/localization';
import { format } from 'somedatelibrary';
// 'mmm' will be formatted based on locale
const dateformat = 'dd-mmm-yyyy';
export const formatdate = (date: number) => format(date, dateformat, locale)
how to mock in a test file
import * as localization from 'src/common/localization';
import { formatdate } from 'src/utils/dateutils';
describe('format date', () => {
test('should be in danish format', () => {
object.defineproperty(localization, 'locale', {
value: 'da-dk'
});
expect(formatdate(1589500800000)).toequal('15-maj-2020');
});
test('should be in us format', () => {
object.defineproperty(localization, 'locale', {
value: 'en-us'
});
expect(formatdate(1589500800000)).toequal('15-may-2020');
});
});
score:2
one of the way for mock variables is the follow solution:
for example exists file ./constants.js
with constants:
export const constatn_1 = 'value 1';
export const constatn_2 = 'value 2';
there is also a file of tests ./file-with-tests.spec.js
in which you need to do mock variables.
if you need to mock several variables you need to use jest.requireactual
to use the real values of the remaining variables.
jest.mock('./constants', () => ({
...jest.requireactual('./constants'),
constatn_1: 'mock value 1',
}));
if you need to mock all variables using jest.requireactual
is optional.
jest.mock('./constants', () => ({
constatn_1: 'mock value 1',
constatn_2: 'mock value 2'
}));
score:3
the most common scenario i needed was to mock a constant used by a class (in my case, a react component but it could be any es6 class really).
@luke's answer worked great for this, it just took a minute to wrap my head around it so i thought i'd rephrase it into a more explicit example.
the key is that your constants need to be in a separate file that you import
, so that this import
itself can be stubbed/mocked by jest
.
the following worked perfectly for me.
first, define your constants:
// src/my-component/constants.js
const my_constant = 100;
export { my_constant };
next, we have the class that actually uses the constants:
// src/my-component/index.jsx
import { my_constant } from './constants';
// this could be any class (e.g. a react component)
class mycomponent {
constructor() {
// use the constant inside this class
this.secret = my_constant;
console.log(`current value is ${this.secret}`);
}
}
export default mycomponent
lastly, we have the tests. there's 2 use cases we want to handle here:
- mock the generate value of
my_constant
for all tests inside this file - allow the ability for a specific test to further override the value of
my_constant
for that single test
the first part is acheived by using jest.mock
at the top of your test file.
the second is acheived by using jest.spyon
to further spy on the exported list of constants. it's almost like a mock on top of a mock.
// test/components/my-component/index.js
import mycomponent from 'src/my-component';
import allconstants from 'src/my-component/constants';
jest.mock('src/my-component/constants', () => ({
get my_constant () {
return 30;
}
}));
it('mocks the value of my_constant', () => {
// initialize the component, or in the case of react, render the component
new mycomponent();
// the above should cause the `console.log` line to print out the
// new mocked value of 30
});
it('mocks the value of my_constant for this test,', () => {
// set up the spy. you can then use any jest mocking method
// (e.g. `mockreturnvalue()`) on it
const myspy = jest.spyon(allconstants, 'my_constant', 'get')
myspy.mockreturnvalue(15);
new mycomponent();
// the above should cause the `console.log` line to print out the
// new mocked value of 15
});
score:5
facing the same issue, i found this blog post very useful, and much simpler than @cyberwombat use case :
https://remarkablemark.org/blog/2018/06/28/jest-mock-default-named-export/
// esmodule.js
export default 'defaultexport';
export const namedexport = () => {};
// esmodule.test.js
jest.mock('./esmodule', () => ({
__esmodule: true, // this property makes it work
default: 'mockeddefaultexport',
namedexport: jest.fn(),
}));
import defaultexport, { namedexport } from './esmodule';
defaultexport; // 'mockeddefaultexport'
namedexport; // mock function
score:5
for me the simplest solution was to redefine the imported object property, as decribed here:
https://flutterq.com/how-to-mock-an-exported-const-in-jest/
// foo.js
export const foo = true; // could be expression as well
// spec file
import * as constants from './foo'
object.defineproperty(constant, 'foo', {value: 1})
score:8
since we can't override/mock the value directly. we can use the below hack
// foo.js
export const foo = true; // could be expression as well
// spec file
import * as constants from './foo'
object.defineproperty(constant, 'foo', {value: 1})
for functions:
object.defineproperty(store, 'doonething', {value: jest.fn()})
score:13
thanks to @luke i was able to expand on his answer for my needs. i had the requirements of:
- only mocking certain values in the file - not all
- running the mock only inside a single test.
turns out that domock()
is like mock()
but doesn't get hoisted. in addition requireactual()
can be used to grab original data.
my config.js
file - i need to mock only part of it
export const something = 'blah'
export const other = 'meh'
my test file
// import { somefunc } from 'some/file' // this won't work with domock - see below
describe('my test', () => {
test('somefunc() does stuff', async () => {
// here i mock the config file which gets imported somewhere deep in my code
jest.domock('config.js', () => {
// grab original
const originalmodule = jest.requireactual('config')
// return original but override some values
return {
__esmodule: true, // depends on your setup
...originalmodule,
something: 'boom!'
}
})
// because `domock` doesn't get hoisted we need to import the function after
const { somefunc } = await import(
'some/file'
)
// now somefunc will use the original config values but overridden with something=boom!
const res = await somefunc()
})
})
depending on other tests you may also need to use resetmodules()
somewhere such as beforeall
or afterall
.
docs:
score:36
unfortunately none of the posted solutions worked for me or to be more precise some did work but threw linting, typescript or compilation errors, so i will post my solution that both works for me and is compliant with current coding standards:
// constants.ts
// configuration file with defined constant(s)
export const someconstantvalue = true;
// module.ts
// this module uses the defined constants
import { someconstantvalue } from './constants';
export const somecheck = () => someconstantvalue ? 'true' : 'false';
// module.test.ts
// this is the test file for module.ts
import { somecheck } from './module';
// jest specifies that the variable must start with `mock`
const mocksomeconstantvaluegetter = jest.fn();
jest.mock('./constants', () => ({
get someconstantvalue() {
return mocksomeconstantvaluegetter();
},
}));
describe('somecheck', () => {
it('returns "true" if someconstantvalue is true', () => {
mocksomeconstantvaluegetter.mockreturnvalue(true);
expect(somecheck()).toequal('true');
});
it('returns "false" if someconstantvalue is false', () => {
mocksomeconstantvaluegetter.mockreturnvalue(false);
expect(somecheck()).toequal('false');
});
});
score:48
there is another way to do it in es6+ and jest 22.1.0+ thanks to getters and spyon.
by default, you cannot spy on primitive types like boolean or number. you can though replace an imported file with your own mock. a getter method still acts like a primitive member but allows us to spy on it. having a spy on our target member you can basically do with it whatever you want, just like with a jest.fn()
mock.
below an example
// foo.js
export const foo = true; // could be expression as well
// subject.js
import { foo } from './foo'
export default () => foo
// subject.spec.js
import subject from './subject'
jest.mock('./foo', () => ({
get foo () {
return true // set some default value
}
}))
describe('subject', () => {
const myspy = jest.spyon(subject.default, 'foo', 'get')
it('foo returns true', () => {
expect(subject.foo).tobe(true)
})
it('foo returns false', () => {
myspy.mockreturnvalueonce(false)
expect(subject.foo).tobe(false)
})
})
Source: stackoverflow.com
Related Query
- How to mock an exported const in jest
- how do you mock a default exported object with jest per test?
- how to change jest mock function return value in each test?
- How to mock React component methods with jest and enzyme
- How to mock history.push with the new React Router Hooks using Jest
- How to mock window.navigator.language using jest
- How to mock out sub-components when unit testing a React component with Jest
- How to mock DataTransfer with Jest
- How do you mock a react component with Jest that has props?
- How to mock BrowserRouter of react-router-dom using jest
- How to mock API calls made within a React component being tested with Jest
- How to mock $.ajax call in JEST
- how to mock AWS library in jest
- React - Jest - Enzyme: How to mock ref properties
- How to mock all files in a folder in jest
- how to mock json.parse() in jest tests
- React: How to mock Auth0 for testing with Jest
- How to mock a React component lifecycle method with Jest and Enzyme?
- Jest how to mock api call
- How to mock or assert whether window.alert has fired in React & Jest with typescript?
- how to mock variables inside a function in jest
- How to mock localStorage.setIem and localStorage.removeItem in JEST
- How to mock window.location.href with Jest in React?
- How to reuse jest mock of react-router's useHistory
- How to mock async function using jest framework?
- How can I mock axios API calls? with using jest
- How to mock navigator mediaDevices for Jest
- How to mock the formik useFormikContext hook when writing unit tests with jest
- Jest unit test with Luxon: how do I mock .setZone('local')
- How to replace a React component with a mock when testing with Jest
More Query from same tag
- Jest encountered an unexpected token when testing react-native with jest
- Deploying ReactJS app Production
- How to setState with <select> after component has mounted and options have been generated?
- Struggling with this.props in nested components
- How to download a file through an API in React?
- Formik in tabs React
- Should component itself prevent unwanted useEffect() calls?
- Warning: React.createElement: type is invalid -- expected a string (for built-in components) (React Webpack Phaser)
- ResizableBox doesn't wrap contents
- How to load data only once in a React function?
- Yup validation based on value of another field
- Transition to a route on successful async Redux action
- React prevState and increment object property +1 not work correctly
- Maximum update depth exceeded error in react hooks
- How to handle filter with multiple parameters React
- After deployment getting 404 error axios post
- firebase2.default.firestore is not a function - React Firebase
- Map an array of objects but only displaying unique values
- Enter text into multi stacked donut chart
- How to add authorization to Response.Header?
- How to I resize fluid image from "gatsby-image" on my index.js page in gatsby?
- Material UI ToggleButtonGroup
- ReactJS call to back-end route to login user with Google/Facebook
- REACT-How to increment value in an object without deconstructors
- How to insert an accordion icon and do list toggling, if html data is coming from API instead of JSON response?
- CORS with SSR with express, react and Axios
- React-chartjs-2 - Each dataset needs a unique key
- React update the value after rendering
- React : printing all past state when updating state
- Update a value in a child node in state