MkMan
MkMan

Reputation: 2191

How to unit test a callback function was called on a React component using Cypress

I am trying to use cypress-react-unit-test to unit test my React components.

In this instance I have a Button, that gets passed a callback function to execute on click. I have the code below but fails immediately at the line highlighted. The error message is expected stub to have been called at least once, but it was never called.

import React from 'react';
import { mount } from 'cypress-react-unit-test';

const Button = ({ onClick }) => (
  <button onClick={onClick} data-test-ref="button">
    Hello
  </button>
);

describe('Button', () => {
  it('should call the onClick function', () => {
    const onClick = cy.stub();

    mount(<Button onClick={onClick} />);
    cy.get(`[data-test-ref=button]`).click();

    // expect(onClick).to.be.called; // fails
  });
});

What am I doing wrong? How do I test that the onClick prop was executed when the button is clicked.

Thanks

Upvotes: 4

Views: 4818

Answers (1)

Richard Matsen
Richard Matsen

Reputation: 23463

Essentially, the expect() is getting executed before the Cypress commands get a chance to run.

You need to chain the expect inside a .then() as per the toggle-spec example,

describe('Button', () => {
  it('should call the onClick function', () => {
    const onClick = cy.stub();

    mount(<Button onClick={onClick} />);
    cy.get(`[data-test-ref=button]`).click()
    .then(() => {
      expect(onClick).to.be.called; // succeeds
    });

  });
});

Or alias the stub as per the stub example,

describe('Button', () => {
  it('should call the onClick function', () => {
    const onClick = cy.stub().as('my-button');

    mount(<Button onClick={onClick} />);
    cy.get(`[data-test-ref=button]`).click();

    cy.get('@my-button').should('have.been.called'); 
  });
});

Upvotes: 9

Related Questions