简体   繁体   中英

How to test onClose prop with Jest and ReactJs

I have a component looking like this, when the button is clicked a modal opens, when X button is clicked, mouse is pressed or esc key is pressed modal closes and calls onClose function, however, Jest report says setIsOpen(false); is not covered.

const MyComponent = () => {
  const [isOpen, setIsOpen] = useState(false);
 
  return (
    <div className="container">
          <button
            onClick={() => {
              setIsOpen(true);
            }}
          />
      <Flow
        isOpen={isOpen}
        onClose={() => {
          setIsOpen(false);
        }}
      />
    </div>
  );
}; 

How can I test if setIsOpen(false); is being called? I tried mocking the useState and check if it was being called, however, this messed up the setIsOpen(true); in the button, being a mock, the modal won't open.

Any ideas?

I will use Enzyme to test the behavior of react component.

Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output

You can use .invoke(invokePropName)(...args) => Any of shallow wrapper to invoke onClose() method of Flow component.

Eg

MyComponent.tsx :

import React, { useState } from 'react';
import { Flow } from './Flow';

export const MyComponent = () => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="container">
      <button
        onClick={() => {
          setIsOpen(true);
        }}
      />
      <Flow
        isOpen={isOpen}
        onClose={() => {
          setIsOpen(false);
        }}
      />
    </div>
  );
};

Flow.tsx

import React from 'react';
export function Flow({ isOpen, onClose }) {
  if (!isOpen) return null;
  return <div onClick={onClose}>close</div>;
}

MyComponent.test.tsx :

import React from 'react';
import { shallow } from 'enzyme';
import { MyComponent } from './MyComponent';
import { Flow } from './Flow';

describe('67027129', () => {
  it('should set open to true', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find(Flow).prop('isOpen')).toBeFalsy();
    wrapper.find('button').simulate('click');
    expect(wrapper.find(Flow).prop('isOpen')).toBeTruthy();
  });

  it('should set open to false', () => {
    const wrapper = shallow(<MyComponent />);
    wrapper.find('button').simulate('click');
    expect(wrapper.find(Flow).prop('isOpen')).toBeTruthy();
    wrapper.find(Flow).invoke('onClose')();
    expect(wrapper.find(Flow).prop('isOpen')).toBeFalsy();
  });
});

unit test result:

 PASS  examples/67027129/MyComponent.test.tsx (10.173 s)
  67027129
    ✓ should set open to true (37 ms)
    ✓ should set open to false (19 ms)

-----------------|---------|----------|---------|---------|-------------------
File             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------------|---------|----------|---------|---------|-------------------
All files        |   76.92 |        0 |      75 |   81.82 |                   
 Flow.tsx        |      40 |        0 |       0 |      50 | 3-4               
 MyComponent.tsx |     100 |      100 |     100 |     100 |                   
-----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        10.908 s, estimated 13 s

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM