Source:  Twitter logo

I'm using Jest to test my React component but I've encountered an error I had never seen before.

here's my <Row/> component:

class Row extends React.Component {

  constructor() {
    super();
    this.state = { userId: '', showDetails: false, showModal: false, status: '', value: '' }
    this.handleStatusChange = this.handleStatusChange.bind(this)
    this.handleModalCancel = this.handleModalCancel.bind(this)
    this.handleModalConfirm = this.handleModalConfirm.bind(this)
    this.showDetailsPanel = this.showDetailsPanel.bind(this)
  }

  showDetailsPanel() {

    if(!this.state.showDetails) {
      this.setState({
        showDetails: true
      });
    } else {
      this.setState({
        showDetails: false
      });
    }
  }

  handleModalCancel() {
    this.setState({
      showModal: false
    });
  }

  handleStatusChange(e) {
    this.setState({
      showModal: true,
      value: e.target.value,
    });
  }

  handleModalConfirm() {
    this.setState({
      showModal: false
    });
    this.props.model.status = this.state.value;
  }

  componentWillMount() {
    this.props.model.fullName = `${this.props.model.firstName} ${this.props.model.lastName}`
  }

  render() {

    const { model, modelProps, actions } = this.props;

    return (
      <div className="c-table__row">
        {this.state.showModal ?
           <Modal
             title="Are you sure?"
             copy={`Are you sure that you want to change the staus of this user to ${this.state.value}?`}
             confirmText="Yes I'm sure"
             cancel={this.handleModalCancel}
             submit={this.handleModalConfirm}
           />
           : null
        }
        <div className="c-table__row-wrapper">
        {modelProps.map((p, i) =>
          <div className={`c-table__item ${model[p] === "Active" || model[p] === "Suspended" || model[p] === "Locked" ? model[p] : ""}`} key={i}>
            {model[p]}
          </div>
        )}
        <div className="c-table__item c-table__item-sm">
          <a onClick={this.showDetailsPanel} className={this.state.showDetails ? "info showing" : "info"}><Icon yicon="Expand_Cross_30_by_30" /></a>
        </div>
      </div>

      {this.state.showDetails ?
        <Details
          tel={model.telephoneNumber}
          dept={model.department}
          role={model.role}
          username={model.username}
          status={model.status}
          statusToggle={this.handleStatusChange}
        />
      : null }
      </div>
    );
  }
}

export default Row;

And here's my test:

import React from 'react';
import {shallow, mount} from 'enzyme';
import { shallowToJson } from 'enzyme-to-json'
import renderer from 'react-test-renderer';
import Row from '../../../src/components/tables/row.jsx';


test('clicking the info button should call showDetailsPanel', () => {

  const component = mount(<Row model={{a: 1, b: 2}} modelProps={['a', 'b']}/>)
  const showDetailsPanel = jest.spyOn(component.instance(), 'showDetailsPanel');
  component.update();
  const button = component.find('.info')

  button.simulate('click')
  expect(showDetailsPanel).toBeCalled();

})

So I'm simply trying to check that when the info button is clicked the showDetailsPanel is called, but it fails with TypeError: jest.spyOn is not a function.
I'm using "jest": "^18.1.0","jest-cli": "^18.1.0","jest-junit": "^1.5.1".

Any idea?

Thanks in advance

You're using Jest version 18.1.0 but jest.spyOn has been added in 19.0.0.

If you want to use it, you need to upgrade Jest.

npm install --save-dev jest@latest

Or if you're using Yarn:

yarn upgrade jest --latest
3 users liked answer #0dislike answer #03
Michael Jungo profile pic
Michael Jungo

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).