I got a very simple react component with following functionallity:
componentDidMount() {
window.scrollTo(0, 0)
}
It seems that you cannot do something like
window.scrollTo = jest.fn()
to spy on scrollTo
function.
Therefor, I want to know what is the best way to spy on this function and assert that it has been used in my tests.
Thanks
In jest the global name space must be accessed by global
not window
.
global.scrollTo = jest.fn()
I had a similar problem and just assigning the spy didn't work for me.
Eventually I was able to get this working with this code
const spyScrollTo = jest.fn();
Object.defineProperty(global.window, 'scrollTo', { value: spyScrollTo });
Then in Jest I was able to check it like this
const spyScrollTo = jest.fn();
describe('myComponent', () => {
beforeEach(() => {
Object.defineProperty(global.window, 'scrollTo', { value: spyScrollTo });
Object.defineProperty(global.window, 'scrollY', { value: 1 });
spyScrollTo.mockClear();
});
it('calls window.scrollTo', () => {
myComponent();
expect(spyScrollTo).toHaveBeenCalledWith({
top: 1,
behavior: 'smooth',
});
});
});
Like Andreas said, you will need to access scrollTo()
via the global namespace. But to spy on it and make assertions, you will need to assign your spy function to a variable. Something like this:
const scrollToSpy = jest.fn();
global.scrollTo = scrollToSpy;
...
expect(scrollToSpy).toHaveBeenCalled();
Dependencies:
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"jest": "^24.8.0"
"jest-environment-enzyme": "^7.1.1",
"jest-enzyme": "^7.1.1",
"jsdom": "^15.1.1"
window.scrollTo = jest.fn()
works fine.
For example:
index.spec.tsx
:
import React, { Component } from 'react';
class SomeComponent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
window.scrollTo(0, 0);
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me!</button>
</div>
);
}
}
export default SomeComponent;
index.spec.tsx
, mock window.scrollTo
in each test case:
import React from 'react';
import { shallow } from 'enzyme';
import SomeComponent from './';
describe('SomeComponent', () => {
test('should handle click', () => {
const wrapper = shallow(<SomeComponent></SomeComponent>);
const mEvent = { preventDefault: jest.fn() };
window.scrollTo = jest.fn();
wrapper.find('button').simulate('click', mEvent);
expect(mEvent.preventDefault).toBeCalled();
expect(window.scrollTo).toBeCalledWith(0, 0);
});
});
jest.config.js
:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'enzyme',
setupFilesAfterEnv: ['jest-enzyme'],
testEnvironmentOptions: {
enzymeAdapter: 'react16'
},
coverageReporters: ['json', 'text', 'lcov', 'clover']
};
Unit test result:
PASS src/stackoverflow/58585527/index.spec.tsx
SomeComponent
✓ should handle click (13ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.932s, estimated 3s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58585527