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
To mock the JavaScript window object using Jest, we can use the jest. spyOn method. let windowSpy; beforeEach(() => { windowSpy = jest. spyOn(window, "window", "get"); }); afterEach(() => { windowSpy.
Here is the unit test: it("should scroll to the second block", () => { const scrollToSecondPart = jest. spyOn(LandingPage. prototype, 'scrollToSecondPart'); const wrapper = shallow(<LandingPage />); const instance = wrapper.
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',
});
});
});
In jest the global name space must be accessed by global
not window
.
global.scrollTo = jest.fn()
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
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With