首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何测试在功能组件中定义的、与DOM元素交互且没有参数的方法

如何测试在功能组件中定义的、与DOM元素交互且没有参数的方法
EN

Stack Overflow用户
提问于 2019-05-27 21:13:45
回答 2查看 301关注 0票数 1

在我的一个按钮(一个React功能组件)上,我遇到了100%测试覆盖率的问题。基本上,当它被单击时,它会执行一些代码,然后还会从这个onClick中调用另一个名为resetButtons的方法。此方法将在应用程序中找到所有类似的按钮,并删除一个类。这是一种抢占行为,因此一次只能有一个按钮为active

到目前为止,我已经通过传入一个模拟的domElement,使用.simulate测试了点击。然后测试是否使用'active'调用了domElement.classList.add方法。

显然,这是一个以DOM为中心的操作,我发现测试位于组件中的resetButtons方法非常困难。特别是考虑到它没有任何方法。

我尝试在组件外部定义resetButtons方法,然后将其导出,以便jest测试可以导入它。然而,我一直无法测试该方法,因为它似乎希望它是间谍或模拟,而不是方法本身。(Matcher error: received value must be a mock or spy function )

下面是react功能组件:

代码语言:javascript
复制
import React from 'react';
import PropTypes from 'prop-types';
import classes from './MainButton.module.scss';

const MainButton = (props) => {
  const resetButtons = () => {
    const elements = document.getElementsByClassName('mainButton');
    for (let i = 0; i < elements.length; i += 1) {
      elements[i].classList.remove('active');
    }
  };

  const handleClick = (event) => {
    if (!event.target.classList.contains('active')) {
      resetButtons();
      event.target.classList.add('active');
      props.setVisualState(props.className.split('-')[0]);
    }
  };

  return (
    <button
      onClick={handleClick}
      type="button"
      className={`${classes.mainButton} ${props.className}`}
    >
      {props.children}
    </button>
  );
};

MainButton.propTypes = {
  children: PropTypes.node,
  className: PropTypes.string,
  setVisualState: PropTypes.func.isRequired,
};

MainButton.defaultProps = {
  children: 'Button',
  className: '',
};

export default MainButton;

下面是测试

代码语言:javascript
复制
import React from 'react';
import { shallow } from 'enzyme';
import MainButton from './MainButton';

describe('MainButton', () => {
  const domElement = { classList: { contains: jest.fn(), remove: jest.fn(), add: jest.fn() } };
  const setVisualStateMock = jest.fn();
  const mainButton = shallow(<MainButton setVisualState={setVisualStateMock} />);

  it(' is rendered properly', () => {
    expect(mainButton).toMatchSnapshot();
  });

  describe('when clicked', () => {
    beforeEach(() => {
      mainButton.find('button').simulate('click', { target: domElement });
    });

    it('it runs `classlist.add` to assign `active` class', () => {
      expect(domElement.classList.add).toHaveBeenCalledWith('active');
    });

    it('it runs set visual state to update `Allergen` container `state`', () => {
      expect(setVisualStateMock).toHaveBeenCalled();
    });
  });
});

目前,覆盖率报告报告的覆盖率为92%,但分支的覆盖率为50,导致问题的线路在第9行( elements[i].classList.remove('active');线路)。

我知道90%的我可能应该继续前进,但这是我想要弄清楚的事情。我觉得解决这个问题会让我成为一个更好的测试者。

希望你们能帮上忙!

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56326822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档