Oliver
Oliver

Reputation: 61

Mock function not being called in Jest + Enzyme test

I have written a test that mocks the sumbitChoice() function as this function is responsible for an API call. The function is called on clicking the button, '#buttonOption1'.

Currently, the test's assertion fails i.e. 'Expected mock function to have been called.'

App.test.js

import React from 'react';
import App from './App';
import { mount, shallow } from 'enzyme';
import { waitForState } from 'enzyme-async-helpers';

describe('App', () => {

 it('should call the submitChoice method on click' , () => {

  //arrange
    const mockSubmitChoice = jest.fn();
    const app = mount(<App submitChoice={ mockSubmitChoice } />);

  //act
    app.find('#buttonOption1').simulate('click');

  //assert
    expect(mockSubmitChoice).toBeCalled();

  })

})

App.js

import React, { Component } from 'react';

class App extends Component {
  constructor() {
    super();

    this.state =  { imageURLs:  [] }
  }

  componentDidMount() {
    fetch('/comparison')
      .then(res => res.json())
      .then(images => this.setState({
         imageURLs: [...this.state.imageURLs, images]
      }))
      // .bind(this);
      console.log(this.state)
  }

  submitChoice(data) {
    fetch('/comparison', {
      method: 'POST',
      body: JSON.stringify([...this.state.imageURLs, data]),
      headers: new Headers({
        'Content-Type': 'application/json'
      })
    }).then(res => res.json())
    .catch(error => console.error('Error:', error))
    .then(response => console.log('Success:', response));
  }


  render() {

    return (
      <div className="App">
        <img id='firstImage' className='image' src={this.state.imageURLs[0]} />
        <img id='secondImage' className='image' src={this.state.imageURLs[1]} />
        <button id='buttonOption1' className='button' onClick={this.submitChoice(this.state.imageURLs[0])}>Select Option 1</button>
      </div>
    );
  }
 }

export default App;

Upvotes: 2

Views: 3066

Answers (3)

Oliver
Oliver

Reputation: 61

I went for a different test method in the end. This passes:

  it('should call the submitChoice method on click', () => {

    //arrange
    const spy = jest.spyOn(App.prototype, 'submitChoice'); 
    const app = shallow(<App />);

    //act
    const button = app.find('#buttonOption1')
    button.simulate('click');

    //assert
    expect(spy).toBeCalled();

 })

Upvotes: 1

Giorgi_Mdivani
Giorgi_Mdivani

Reputation: 383

You are not binding your function to onClick event, you are calling it and since it return nothing you are basically binding undefined to onclick.

this:

onClick={this.submitChoice(this.state.imageURLs[0])} 

is same as this:

onClick-{undefined}

because

console.log(this.submitChoice(this.state.imageURLs[0])) // output will be undefined

so just change your code like this:

 onClick={this.submitChoice}

and find another way to pass data, since you are just passing static dammy data it should not be much issue anyway.

Upvotes: 0

Bojan Ivanac
Bojan Ivanac

Reputation: 1180

Try to bind your this.submitChoice() function in the constructor.

this.submitChoice = this.submitChoice.bind(this)

Upvotes: 0

Related Questions