javascript - 开 Jest | Enzyme 如何测试 onClick 事件期间是否调用组件内的函数?

标签 javascript reactjs jestjs enzyme

我如何测试 handleLogoutdata-test="logout"时函数被触发按钮被点击?

const NavBar = props => {
  const handleClick = (e, destination) => {
    e.preventDefault();
    props.history.push(`/${destination || ""}`);
  };

  // Test when data-test="logout" is clicked, handleLogout is called.
  const loginFormat =
    Object.keys(props.userDetails).length === 0 ? (
      <Fragment>
        <button onClick={e => handleClick(e, "login")}>Login</button>
        <button onClick={e => handleClick(e, "register")}>Register</button>
      </Fragment>
    ) : (
      // This button
      <button data-test="logout" onClick={e => handleLogout(e)}>
        Logout
      </button>
    );

  const handleLogout = e => {
    e.preventDefault();
    props.logoutUser();
    handleClick(e);
  };

  return (
    <header className="NavBar">
      <h2>PalettePicker</h2>
      <form className="navbar-form">{loginFormat}</form>
    </header>
  );
};

我当前的尝试:

  let mockUserDetails = { username: "steve", id: 123 };
  beforeEach(() => {
    wrapper = shallow(
      <NavBar
        userDetails={mockUserDetails}
        history={historyMock}
      />
    );
  });

  it("should invoke the handleLogout function when logout is clicked", () => {
    const mock = jest.spyOn(wrapper, "handleLogout");
    const button = wrapper.find('[data-test="logout"]');
    // console.log(button.debug());
    button.simulate("click", { preventDefault() {} });
  });

我收到此错误:Cannot spy the handleLogout property because it is not a function; undefined given instead ,所以我什至无法达到预期 block ,因为 spyOn抛出错误...有什么想法吗?

最佳答案

您无法监视 handlelogout 函数,因为它是在函数范围内定义的。这是私有(private)

为了测试handlelogout函数,我们需要模拟logout按钮上的点击事件,将模拟事件对象传递给事件处理程序。此外,您还必须将 loguUser 方法传递给组件,最后检查历史记录的路径名是否按预期路径 / 更改。

使用createMemoryHistory函数创建一个带有初始历史堆栈/home的内存历史记录。这意味着我们登录的用户当前位于 /home 进行测试用例。

例如

NavBar.jsx:

import React, { Fragment } from 'react';

export const NavBar = (props) => {
  const handleClick = (e, destination) => {
    e.preventDefault();
    props.history.push(`/${destination || ''}`);
  };

  const loginFormat =
    Object.keys(props.userDetails).length === 0 ? (
      <Fragment>
        <button onClick={(e) => handleClick(e, 'login')}>Login</button>
        <button onClick={(e) => handleClick(e, 'register')}>Register</button>
      </Fragment>
    ) : (
      // This button
      <button data-test="logout" onClick={(e) => handleLogout(e)}>
        Logout
      </button>
    );

  const handleLogout = (e) => {
    e.preventDefault();
    props.logoutUser();
    handleClick(e);
  };

  return (
    <header className="NavBar">
      <h2>PalettePicker</h2>
      <form className="navbar-form">{loginFormat}</form>
    </header>
  );
};

NavBar.test.jsx:

import { shallow } from 'enzyme';
import React from 'react';
import { NavBar } from './NavBar';
import { createMemoryHistory } from 'history';

describe('57703870', () => {
  it('should invoke the handleLogout function when logout is clicked', () => {
    const historyMock = createMemoryHistory({ initialEntries: ['/home'] });
    const props = {
      logoutUser: jest.fn(),
      userDetails: { username: 'steve', id: 123 },
      history: historyMock,
    };
    const wrapper = shallow(<NavBar {...props} />);
    expect(props.history.location.pathname).toEqual('/home');
    const button = wrapper.find('[data-test="logout"]');
    const mEvent = { preventDefault: jest.fn() };
    button.simulate('click', mEvent);
    expect(mEvent.preventDefault).toBeCalledTimes(2);
    expect(props.logoutUser).toBeCalledTimes(1);
    expect(props.history.location.pathname).toEqual('/');
  });
});

测试结果:

 PASS  examples/57703870/NavBar.test.jsx (8.534 s)
  57703870
    ✓ should invoke the handleLogout function when logout is clicked (9 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |   86.67 |       75 |   66.67 |   85.71 |                   
 NavBar.jsx |   86.67 |       75 |   66.67 |   85.71 | 12-13             
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.63 s

关于javascript - 开 Jest | Enzyme 如何测试 onClick 事件期间是否调用组件内的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57703870/

相关文章:

javascript - 使 propTypes 成为强制性的并且有 stateTypes

javascript - Webpack:将多个 js 框架捆绑到一个包中?

reactjs - 当我使用 useSelector 时,React 测试库无法工作

typescript - Jest + Typescript + 绝对路径 (baseUrl) 给出错误 : Cannot find module

javascript - 如何对非导出函数进行单元测试?

javascript - 解析/转换 cookie 为 JSON 格式

javascript - 通过复选框更改列表框的内容

javascript - 在内联样式中使用状态变量

javascript - 鼠标悬停时调用插件时会有延迟,同时鼠标移开时也会取消

javascript - 如何在 Javascript 中合并键并将它们的值相加?