0

I am very new to React and want to be able to test that a function was called when a button is clicked, however I cannot get this working. I have tried the answers at posts such as: How to test a function is called in react jest? and others but to no avail.

My component snippet is:

// Import React core components
import React from 'react';

class ScrollToTop extends React.Component {

    /**
    * Method to scroll top the top of the page on click
    */
    scrollToTopEvent() {
        window.scrollTo(0, 0);
    };

    render() {
        return(

            <div id="scroll-to-top-container">
                {
                    this.state.showScrollToTop ? (
                        <button id="scroll-to-top" className="button button-secondary" onClick={ this.scrollToTopEvent }>Scroll to top</button>
                    ) : (
                        null
                    )
                }
            </div>

        );
     }

     export default ScrollToTop;

}

And here is my test that I am attempting to get working, cobbled together from various Stackoverflows and articles:

import React from 'react';
import { shallow } from 'enzyme';
import ScrollToTop from "./scroll-to-top";

describe(`Tests the scroll-to-top.js file content`, () => {

    const scrollToTop = shallow(<ScrollToTop />);
    const instance = scrollToTop.instance();

    describe(`Tests scrollToTopEvent`, () => {

        it(`should ensure the scrollToTop method was called on button click`, () => {

            scrollToTop.setState({ showScrollToTop: true });

            jest.spyOn(instance, 'scrollToTopEvent');

            const scrollToTopButton = scrollToTop.find(`#scroll-to-top`);

            scrollToTopButton.simulate('click');

            scrollToTop.update();

            expect(instance.scrollToTopEvent).toHaveBeenCalled();
    
        });

    });

});

The error I get in the console is:

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

> 96 |             expect(instance.scrollToTopEvent).toHaveBeenCalled();

Any help for this n00b would be much appreciated!

Dan Hodson
  • 309
  • 4
  • 18

1 Answers1

0

To be enable enzyme to track a function call you have to spy on that function, like this:

const scrollToTopEventSpy = jest.spyOn(ScrollToTop.prototype, 'scrollToTopEvent);

Then you can test the calls like this:

expect(scrollToTopEventSpy).toHaveBeenCalled();
k-wasilewski
  • 3,943
  • 4
  • 12
  • 29
  • Thank you for your reply, however this gives me the same result. – Dan Hodson Aug 15 '20 at 20:39
  • How about trying to wait for `window.scrollTo()`, meaning placimg your `expect` in a `setTimeout()` ? – k-wasilewski Aug 16 '20 at 08:36
  • Thanks, I did try that actually but it gives a false positive. Wrapping the expect in a setTimeout will pass the test, but inversely setting it to .not.toHaveBeenCalled() will also pass the test, which should fail. – Dan Hodson Aug 16 '20 at 10:02
  • You have to setup the test like this `it('dfdfsdfsg', (done) => {...})` and put a `done()` right after the `expect` statement, inside the `setTimeout()` – k-wasilewski Aug 16 '20 at 12:27