I'm trying to work out execution scopes in jest tests.
I have a react component with the following line being executed during the render:
console.log(fun().m1());
Here's three example of jest of tests
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SimpleInput from './SimpleInput';
import { fun } from './util';
jest.mock('./util', () => ({
fun: jest.fn().mockImplementation(() => ({ m1: jest.fn() })),
}));
describe('SimpleInput', () => {
test("should have '' initialValue by default", () => {
const simpleInput = shallow(<SimpleInput />);
expect(simpleInput.prop('value')).toBe('');
});
});
Outcome:
TypeError: Cannot read property 'm1' of undefined
If I move the mockImplementation to the following:
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SimpleInput from './SimpleInput';
import { fun } from './util';
jest.mock('./util');
describe('SimpleInput', () => {
fun.mockImplementation(() => ({ m1: jest.fn() }));
test("should have '' initialValue by default", () => {
const simpleInput = shallow(<SimpleInput />);
expect(simpleInput.prop('value')).toBe('');
});
});
Outcome:
TypeError: Cannot read property 'm1' of undefined
And finally:
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SimpleInput from './SimpleInput';
import { fun } from './util';
jest.mock('./util');
describe('SimpleInput', () => {
beforeEach(() => {
fun.mockImplementation(() => ({ m1: jest.fn() }));
});
test("should have '' initialValue by default", () => {
const simpleInput = shallow(<SimpleInput />);
expect(simpleInput.prop('value')).toBe('');
});
});
Outcome: it passes.
My question is if I can't execute the mock implementation outside of the beforeEach or each particular test case, how can I add the following to the jest setup files which seems to be failing at the moment:
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener, // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
In such case, you may want to use jest.spyOn. This will add a spy over the original method and you then can perform any kind of mocking you need :)
let performanceNowSpy
beforeEach(() => {
performanceNowSpy = jest.spyOn(window.performance, 'now')
})
afterEach(() => {
performanceNowSpy.mockReset()
})
afterAll(() => {
performanceNowSpy.mockRestore()
})
test('meaningful test name', () => {
performanceNowSpy.mockReturnValueOnce(0)
// A simple example.
// `performance.now()` can be called from another module too.
expect(performance.now()).toBe(0)
})