最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I test a function inside a component by using jest? - Stack Overflow

programmeradmin7浏览0评论

I have a unit testing coverage report for a ponent MyCheckbox.js.

coverage

How do I test the onCheckmarkPress() function in MyCheckbox.js?

Here is the implementation of MyCheckbox.js:

import * as React from 'react';

import { Pressable, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';

/**
 *
 * @param {() => void} props.onUpdate called when checkbox is pressed
 * @return {JSX.Element}
 * @constructor
 */
const MyCheckbox = (props) => {
  const [checked, onChange] = useState(false);
  function onCheckmarkPress() {
    onChange((prev) => {
      let checked = !prev;
      props.onUpdate(checked);
      return checked;
    });
  }

  return (
    <Pressable
      style={[styles.checkboxBase, checked && styles.checkboxChecked]}
      onPress={onCheckmarkPress}
    >
      {checked && <Ionicons name="checkmark" size={24} color="black" />}
    </Pressable>
  );
};

const styles = StyleSheet.create({
  checkboxBase: {
    width: 35,
    height: 35,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
    borderWidth: 2,
    borderColor: 'white',
    backgroundColor: 'white',
  },

  checkboxChecked: {
    backgroundColor: '#C4C4C4',
  },
});

export default MyCheckbox;

I have a unit testing coverage report for a ponent MyCheckbox.js.

coverage

How do I test the onCheckmarkPress() function in MyCheckbox.js?

Here is the implementation of MyCheckbox.js:

import * as React from 'react';

import { Pressable, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';

/**
 *
 * @param {() => void} props.onUpdate called when checkbox is pressed
 * @return {JSX.Element}
 * @constructor
 */
const MyCheckbox = (props) => {
  const [checked, onChange] = useState(false);
  function onCheckmarkPress() {
    onChange((prev) => {
      let checked = !prev;
      props.onUpdate(checked);
      return checked;
    });
  }

  return (
    <Pressable
      style={[styles.checkboxBase, checked && styles.checkboxChecked]}
      onPress={onCheckmarkPress}
    >
      {checked && <Ionicons name="checkmark" size={24} color="black" />}
    </Pressable>
  );
};

const styles = StyleSheet.create({
  checkboxBase: {
    width: 35,
    height: 35,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
    borderWidth: 2,
    borderColor: 'white',
    backgroundColor: 'white',
  },

  checkboxChecked: {
    backgroundColor: '#C4C4C4',
  },
});

export default MyCheckbox;

This is how I attempt the test case:

import React from 'react'
import MyCheckbox from '../MyCheckbox';
import {fireEvent, render, screen} from "@testing-library/react-native";
import '@testing-library/jest-dom';

it("works", () => {
    const onUpdateMock = jest.fn();
    render(<MyCheckbox onUpdate={onUpdateMock} />);

    expect(onUpdateMock).toHaveBeenCalledTimes(0);
    expect(screen.queryByTestId("checkIcon")).toBeNull();

    const pressable = screen.getByRole("pressable");
    fireEvent.press(pressable);

    expect(onUpdateMock).toHaveBeenCalledTimes(1);
    expect(screen.queryByTestId("checkIcon")).toBeInTheDocument(); // check that the icon is rendered
});

However, I am getting the error "Unable to find an element with accessibilityRole: pressable". And will this cover the red lines marked in the coverage report?

Share Improve this question edited Oct 13, 2022 at 0:30 YPZ404 asked Oct 11, 2022 at 4:17 YPZ404YPZ404 931 gold badge1 silver badge8 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

You should test the behaviour of your ponent, so it would look sth like this:

  1. Render the ponent
  2. Find the Pressable ponent
  3. Make sure that check icon is not displayed
  4. emulate the click event on Pressable ponent or other event (touch?) it responds to
  5. Check if check icon is displayed

This kind of test will give you the coverage and the functionality tested. Please provide the Pressable source if you need more detailed answer, it is hard to tell if it is button or some other implementation.

You can use the React Testing Library to achieve all of above steps.

Assuming your MyCheckbox works like this:

const MyCheckbox = (props) => {
  const [checked, onChange] = React.useState(false);

  const onCheckmarkPress = () => {
    onChange((prev) => {
      let checked = !prev;
      props.onUpdate(checked);
      return checked;
    })
  }

  return (
    <button onClick={onCheckmarkPress}>
      {checked && <IonIcon data-testid="checkIcon" name="checkmark" />}
    </button>
  );
};

You could test it like this:

import { fireEvent, render, screen } from "@testing-library/react";
import MyCheckBox from "../MyCheckbox";

it("should work", () => {
  const onUpdateMock = jest.fn();
  render(<MyCheckBox onUpdate={onUpdateMock} />);
  expect(screen.queryByTestId("checkIcon")).not.toBeInTheDocument(); // check that the icon is not rendered
  const btn = screen.getByRole("button"); // get the button (pressable)
  fireEvent.click(btn); // click it

  expect(screen.getByTestId("checkIcon")).toBeInTheDocument(); // check that the icon is displayed
  expect(onUpdateMock).toHaveBeenCalledTimes(1); // make sure that the onUpdate function that was passed via props was clicked
});
发布评论

评论列表(0)

  1. 暂无评论