[javascript] Jest에서 버튼 클릭 시뮬레이션

버튼 클릭을 시뮬레이션하는 것은 매우 쉽고 표준적인 작업처럼 보입니다. 그러나 Jest.js 테스트에서는 작동하지 않습니다.

이것은 내가 시도한 것입니다 (또한 jQuery를 사용하여 수행합니다).하지만 아무것도 트리거하지 않는 것 같습니다.

import { mount } from 'enzyme';

page = <MyCoolPage />;
pageMounted = mount(page);

const button = pageMounted.find('#some_button');
expect(button.length).toBe(1); // It finds it alright
button.simulate('click'); // Nothing happens



답변

# 1 Jest 사용

다음은 Jest 모의 콜백 함수를 사용하여 클릭 이벤트를 테스트하는 방법입니다.

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

describe('Test Button component', () => {
  it('Test click event', () => {
    const mockCallBack = jest.fn();

    const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));
    button.find('button').simulate('click');
    expect(mockCallBack.mock.calls.length).toEqual(1);
  });
});

나는 또한 효소 라는 모듈을 사용하고 있습니다. Enzyme은 React 컴포넌트를보다 쉽게 ​​주장하고 선택할 수있게 해주는 테스트 유틸리티입니다.

# 2 Sinon 사용

또한 독립 실행 형 테스트 스파이, JavaScript 용 스텁 및 모의 인 Sinon 이라는 다른 모듈을 사용할 수 있습니다 . 이것이 어떻게 보이는지 :

import React from 'react';
import { shallow } from 'enzyme';
import sinon from 'sinon';

import Button from './Button';

describe('Test Button component', () => {
  it('simulates click events', () => {
    const mockCallBack = sinon.spy();
    const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));

    button.find('button').simulate('click');
    expect(mockCallBack).toHaveProperty('callCount', 1);
  });
});

# 3 자신의 스파이 사용

마지막으로 자신 만의 순진한 스파이를 만들 수 있습니다 (유효한 이유가없는 한이 접근 방식을 권장하지 않습니다).

function MySpy() {
  this.calls = 0;
}

MySpy.prototype.fn = function () {
  return () => this.calls++;
}

it('Test Button component', () => {
  const mySpy = new MySpy();
  const mockCallBack = mySpy.fn();

  const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));

  button.find('button').simulate('click');
  expect(mySpy.calls).toEqual(1);
});


답변

수락 된 답변의 솔루션은 더 이상 사용되지 않습니다.

# 4 직접 prop 호출

Enzyme 시뮬레이션은 버전 4에서 제거되어야합니다. 메인 메인테이너는 시뮬레이션이 내부적으로 수행하는 prop 함수를 직접 호출하는 것을 제안합니다. 한 가지 해결책은 이러한 props를 호출하는 것이 옳은 일을하는지 직접 테스트하는 것입니다. 또는 인스턴스 메서드를 모의하고, prop 함수가 호출하는지 테스트하고, 인스턴스 메서드를 단위 테스트 할 수 있습니다.

클릭을 호출 할 수 있습니다. 예를 들면 다음과 같습니다.

wrapper.find('Button').prop('onClick')()

또는

wrapper.find('Button').props().onClick()

지원 중단에 대한 정보 : .simulate () 지원 중단
# 2173


답변

Jest를 사용하면 다음과 같이 할 수 있습니다.

test('it calls start logout on button click', () => {
    const mockLogout = jest.fn();
    const wrapper = shallow(<Component startLogout={mockLogout}/>);
    wrapper.find('button').at(0).simulate('click');
    expect(mockLogout).toHaveBeenCalled();
});


답변

클릭시 작성된 핸들러를 호출하려면 다음과 같이 사용할 수 있습니다.

import { shallow } from 'enzyme'; // Mount is not required

page = <MyCoolPage />;
pageMounted = shallow(page);

// The below line will execute your click function
pageMounted.instance().yourOnClickFunction();


답변

형제 의견에서 제안 된 솔루션 외에도 테스트 접근 방식 을 약간 변경 하고 전체 페이지를 한 번에 테스트하지 않고 (깊은 하위 구성 요소 트리 사용) 격리 된 구성 요소 테스트를 수행 할 수 있습니다. 이렇게하면 onClick()및 유사한 이벤트의 테스트가 간단 해집니다 (아래 예 참조).

아이디어는 한 번에 하나의 구성 요소 만 테스트 하고 모든 구성 요소를 함께 테스트하는 것이 아닙니다 . 이 경우 모든 자식 구성 요소는 jest.mock () 함수를 사용하여 모의 처리 됩니다.

다음은 Jestreact-test-renderer를 사용하여 onClick()격리 된 SearchForm구성 요소 에서 이벤트를 테스트 하는 방법의 예입니다 .

import React from 'react';
import renderer from 'react-test-renderer';
import { SearchForm } from '../SearchForm';

describe('SearchForm', () => {
  it('should fire onSubmit form callback', () => {
    // Mock search form parameters.
    const searchQuery = 'kittens';
    const onSubmit = jest.fn();

    // Create test component instance.
    const testComponentInstance = renderer.create((
      <SearchForm query={searchQuery} onSearchSubmit={onSubmit} />
    )).root;

    // Try to find submit button inside the form.
    const submitButtonInstance = testComponentInstance.findByProps({
      type: 'submit',
    });
    expect(submitButtonInstance).toBeDefined();

    // Since we're not going to test the button component itself
    // we may just simulate its onClick event manually.
    const eventMock = { preventDefault: jest.fn() };
    submitButtonInstance.props.onClick(eventMock);

    expect(onSubmit).toHaveBeenCalledTimes(1);
    expect(onSubmit).toHaveBeenCalledWith(searchQuery);
  });
});


답변

버튼 컴포넌트에 대해 약간의 테스트가 필요했습니다. 이 테스트는 나를 위해 작동합니다 😉

import { shallow } from "enzyme";
import * as React from "react";
import Button from "../button.component";

describe("Button Component Tests", () => {
    it("Renders correctly in DOM", () => {
        shallow(
            <Button text="Test" />
        );
    });
    it("Expects to find button HTML element in the DOM", () => {
        const wrapper = shallow(<Button text="test"/>)
        expect(wrapper.find('button')).toHaveLength(1);
    });

    it("Expects to find button HTML element with className test in the DOM", () => {
        const wrapper = shallow(<Button className="test" text="test"/>)
        expect(wrapper.find('button.test')).toHaveLength(1);
    });

    it("Expects to run onClick function when button is pressed in the DOM", () => {
        const mockCallBackClick = jest.fn();
        const wrapper = shallow(<Button onClick={mockCallBackClick} className="test" text="test"/>);
        wrapper.find('button').simulate('click');
        expect(mockCallBackClick.mock.calls.length).toEqual(1);
    });
});


답변