Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simulate('scroll') on a div inside a React component returns `AssertionError: expected false to be true`

I have a React component I'm writing some tests for. I'd like to test that when a div in the component is scrolled it triggers the function listening for that event, onScroll. Unfortunately Enzyme's simulate('click') doesn't seem to call my spy function, as I'd expect.

My component

import React from 'react';
import ReactDOM from 'react-dom';
import jQuery from 'jquery';
const $ = jQuery;

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.handleScroll = this.handleScroll.bind(this);
  }

  handleScroll(event) {
    return true;
  }

  render() {
    return(
      <div className="my-component" onScroll={this.handleScroll}>
        <h1>Hello world</h1>
      </div>
    );
  }
}

export default MyComponent;

My Test

import { expect } from 'chai';
import { shallow, mount, render } from 'enzyme';
import { spy } from 'sinon';
import jsdom from 'jsdom';;

import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from 'react-addons-test-utils';
import MyComponent from '../views/components/my-component';

describe("<MyComponent />", () => {
  it('should trigger pagination when div.search-box scrolls', () => {
    const component = mount(<MyComponent />);
    const handleScrollSpy = spy(component.node, 'handleScroll');
    component
      .find('.my-component')
      .simulate('scroll')

    expect(handleScrollSpy.called).to.be.true;
  });
});

This returns: AssertionError: expected false to be true

I've tried calling the function within the test and it cause the callCount to be 1

component.node.handleScroll();
console.log("Call count: ", handleScrollSpy.callCount);

This makes me think the problem with my test is to do with the simulate part…

component
      .find('.search-box')
      .simulate('click')

Can someone confirm for me if i'm approaching this correctly or if i'm indeed doing something wrong, please?

Thanks.


Edit

Further reading of the Enzyme .simulate docs revealed the following:

Even though the name would imply this simulates an actual event, .simulate() will in fact target the component's prop based on the event you give it. For example, .simulate('click') will actually get the onClick prop and call it.

I wonder if it's because i'm not passing the onScroll as a prop that the .simulate isn't triggering the handleScroll function at the moment.

like image 323
Pete Avatar asked Nov 09 '22 09:11

Pete


1 Answers

I've not used Sinon for spying but it may be worth rewriting your handleScroll:

handleScroll = (event) => {
  return true;
}

The fat arrow will auto bind 'this' for you, which means you can remove this.handleScroll = ... in the constructor.

Another option is to test the result of the handleScroll function (this is obviously tricky while it just returns true) rather than testing it was called.

Finally you could test that the component render created a div with the onScroll property set to this.handleScroll and then test handleScroll separately.

like image 134
Paul Sturgess Avatar answered Nov 14 '22 22:11

Paul Sturgess