Enzyme: componentWillUpdate spy not run as expected

Created on 19 Jun 2017  Â·  4Comments  Â·  Source: enzymejs/enzyme

I using enzyme with my project test, everything goes well, but life cycle method。
e.g
This is component

export class CheckScrollModal extends React.PureComponent {

  componentWillUpdate(props) {
    if (props.shown) {
      this.handleScroll();
    } else {
      this.container.scrollTop = 0;
    }
  }

  handleScroll() {
    if (this.container &&
        this.container.getBoundingClientRect().bottom > this.flag.getBoundingClientRect().bottom) {
      this.props.onScrollToBottom();
    }
  }
...
}

This is my test case

it('should trigger componentWillUpdate correctly', () => {
    const { component } = setup();// like wrapper
    const _ins = component.instance();
    const componentWillUpdate = expect.spyOn(_ins, 'componentWillUpdate');
    const handleScroll = expect.spyOn(_ins, 'handleScroll');
    component.setProps({ shown: true });
    expect(componentWillUpdate).toHaveBeenCalled();//right
     expect(handleScroll).toHaveBeenCalled();// wrong
  });

This componentWillUpdate had been called, but handleScroll was not been called, i am confused that if componentWillUpdate had been called, handleScroll should be trigger yet, why program not entry inner of function?
thanks.

Need More Information Need To Reproduce

Most helpful comment

@clownvary - Making some approximations of your setup, I can't replicate this. I'm curious what your setup and expect might be doing.

node version: 6.10.3
npm version: 3.10.10

package.json:

{
  "scripts": {
    "test": "./node_modules/.bin/mocha test.js"
  },
  "dependencies": {
    "chai": "3.5.0",
    "enzyme": "2.9.0",
    "mocha": "3.2.0",
    "react": "15.4.1",
    "react-addons-test-utils": "15.4.1",
    "react-dom": "15.4.1",
    "sinon": "1.15.4"
  }
}

CheckScrollModal.js:

var React = require('react');

class CheckScrollModal extends React.PureComponent {

  componentWillUpdate(props) {
    if (props.shown) {
      this.handleScroll();
    }
  }

  handleScroll() {
    return 1;
  }

  render() {
    return React.createElement('div');
  }
}

module.exports = CheckScrollModal;

test.js:

var React = require('react');
var expect = require('chai').expect;
var shallow = require('enzyme').shallow;
var CheckScrollModal = require('./CheckScrollModal.js');
var spyOn = require('sinon').spy;

describe('basic component functions', () => {
  it('renders a react component instance', function () {
    var wrapper = shallow(React.createElement(CheckScrollModal));
    expect(wrapper.instance()).to.exist;
  });

  it('should trigger componentWillUpdate correctly', () => {
    const component = shallow(React.createElement(CheckScrollModal));
    const _ins = component.instance();
    const componentWillUpdate = spyOn(_ins, 'componentWillUpdate');
    const handleScroll = spyOn(_ins, 'handleScroll');
    component.setProps({ shown: true });
    expect(componentWillUpdate.calledOnce).to.be.true;
    expect(handleScroll.calledOnce).to.be.true;
  });
});

npm i && npm run test
both my tests pass.

All 4 comments

@clownvary - Making some approximations of your setup, I can't replicate this. I'm curious what your setup and expect might be doing.

node version: 6.10.3
npm version: 3.10.10

package.json:

{
  "scripts": {
    "test": "./node_modules/.bin/mocha test.js"
  },
  "dependencies": {
    "chai": "3.5.0",
    "enzyme": "2.9.0",
    "mocha": "3.2.0",
    "react": "15.4.1",
    "react-addons-test-utils": "15.4.1",
    "react-dom": "15.4.1",
    "sinon": "1.15.4"
  }
}

CheckScrollModal.js:

var React = require('react');

class CheckScrollModal extends React.PureComponent {

  componentWillUpdate(props) {
    if (props.shown) {
      this.handleScroll();
    }
  }

  handleScroll() {
    return 1;
  }

  render() {
    return React.createElement('div');
  }
}

module.exports = CheckScrollModal;

test.js:

var React = require('react');
var expect = require('chai').expect;
var shallow = require('enzyme').shallow;
var CheckScrollModal = require('./CheckScrollModal.js');
var spyOn = require('sinon').spy;

describe('basic component functions', () => {
  it('renders a react component instance', function () {
    var wrapper = shallow(React.createElement(CheckScrollModal));
    expect(wrapper.instance()).to.exist;
  });

  it('should trigger componentWillUpdate correctly', () => {
    const component = shallow(React.createElement(CheckScrollModal));
    const _ins = component.instance();
    const componentWillUpdate = spyOn(_ins, 'componentWillUpdate');
    const handleScroll = spyOn(_ins, 'handleScroll');
    component.setProps({ shown: true });
    expect(componentWillUpdate.calledOnce).to.be.true;
    expect(handleScroll.calledOnce).to.be.true;
  });
});

npm i && npm run test
both my tests pass.

@dcolucci Your code gave me great inspiration, i have fixed this problem, thank u guy.

I did test the same u for componentWillMount, but it returns undefined instead true

const wrapper = mount(<ProductItemPoint product={product}/>)
const spy = jest.spyOn(wrapper.instance(), 'componentWillMount')
expect(wrapper.state().tempPoint).toEqual(2)
expect(spy.calledOnce).toEqual(true)

@hoaibkdn spying on it after the method is called doesn't do anything. Try spyOn(ProductItemPoint.prototype, 'componentWillMount') - before invoking mount.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mattkauffman23 picture mattkauffman23  Â·  3Comments

andrewhl picture andrewhl  Â·  3Comments

timhonders picture timhonders  Â·  3Comments

modemuser picture modemuser  Â·  3Comments

aweary picture aweary  Â·  3Comments