programing

Jest에서 onChange 함수 테스트

kakaobank 2023. 3. 28. 22:04
반응형

Jest에서 onChange 함수 테스트

나는 제스트와 테스트에 비교적 익숙하지 않다.입력 요소가 있는 구성 요소가 있습니다.

import * as React from "react";

export interface inputProps{
    placeholder: string;
    className: string;
    value: string;
    onSearch: (depID: string) => void;
}

onSearch(event: any){
    event.preventDefault();
    //the actual onclick event is in another Component
    this.props.onSearch(event.target.value.trim());
}

export class InputBox extends React.Component<inputProps, searchState> {
  render() {
        return (
            <input
                onChange={this.onSearch} //need to test this
                className={this.props.className} 
                type="text"
                value={this.props.value}
                placeholder={this.props.placeholder} />
        );
    }
}

그 입력 요소를 체크하는 테스트를 원합니다.onChange입력 요소의 기능을 받아들이는 함수입니다.valueAtribute를 파라미터로 지정합니다.지금까지 제가 해 온 일은 다음과 같습니다.

//test to see the input element's onchange 
//returns a function that takes its value as a param
it("onChange param is the same value as the input value", () => {
    const mockFn = jest.fn();
    const input = enzyme.shallow(<InputBox 
                                    value="TestVal"
                                    placeholder="" 
                                    className="" 
                                    onSearch={mockFn}/>);


       input.find('input').simulate('change',  { preventDefault() {} });
       expect(mockFn.mock.calls).toBe("TestVal");
    });

번째 솔루션에서 벗어납니다.Jest 및 https://facebook.github.io/jest/docs/en/mock-functions.html에서 버튼을 클릭해 시뮬레이션을 수행합니다.

Edit: 상기를 실행하면 다음 오류가 발생합니다.

 TypeError: Cannot read property 'value' of undefined

코드 스니펫의 구문은 다음과 같습니다.

import React from 'react';

export default class InputBox extends React.Component {
  onSearch(event) {
    event.preventDefault();
    this.props.onSearch(event.target.value.trim());
  }
  render () { return (<input onChange={this.onSearch.bind(this)} />); }
}

테스트에 불합격하는 이유는 마찬가지로preventDefault이벤트 오브젝트에 대한 함수, 또한 다른 속성을 정의해야 합니다.onSearch기능.

it('should call onChange prop', () => {
  const onSearchMock = jest.fn();
  const event = {
    preventDefault() {},
    target: { value: 'the-value' }
  };
  const component = enzyme.shallow(<InputBox onSearch={onSearchMock} />);
  component.find('input').simulate('change', event);
  expect(onSearchMock).toBeCalledWith('the-value');
});

얕은 렌더링을 사용하기 때문에 이전 테스트 코드에서는 이벤트 모양을 정의해야 합니다.대신 실제 입력값이 사용되고 있는지 테스트하는 경우onSearch전체 렌더링을 시도하기 위해 필요한 함수enzyme.mount:

it('should call onChange prop with input value', () => {
  const onSearchMock = jest.fn();
  const component = enzyme.mount(<InputBox onSearch={onSearchMock} value="custom value" />);
  component.find('input').simulate('change');
  expect(onSearchMock).toBeCalledWith('custom value');
});

TypeScript를 사용한 테스트(및 위의 답변에서 차용)의 경우, 타입의 강제성을 실행할 필요가 있습니다(as React.ChangeEvent<HTMLInputElement>)는, 린터가 시그니처를 호환성이 있는 것으로 인식할 수 있도록 하기 위해서 다음과 같이 합니다.

리액트 파일

export class InputBox extends React.Component<inputProps, searchState> {
  onSearch(event: React.ChangeEvent<HTMLInputElement>){
    event.preventDefault();
    //the actual onclick event is in another Component
    this.props.onSearch(event.target.value.trim());
  }

  render() {
    return (
      <input
        onChange={this.onSearch} //need to test this
        className={this.props.className} 
        type="text"
        value={this.props.value}
        placeholder={this.props.placeholder} />
      );
  }
}

테스트 파일

it('should call onChange prop', () => {
  const onSearchMock = jest.fn();
  const event = {
    target: { value: 'the-value' }
  } as React.ChangeEvent<HTMLInputElement>;
  const component = enzyme.shallow(<InputBox onSearch={onSearchMock} />);
  component.find('input').simulate('change', event);
  expect(onSearchMock).toBeCalledWith('the-value');
});

또는 다른 방법으로

it('should call onChange prop', () => {
  const onSearchMock = jest.fn();
  const event = {
    target: { value: 'the-value' }
  } as React.ChangeEvent<HTMLInputElement>;
  const component = enzyme.mount<InputBox>(<InputBox onSearch={onSearchMock} />);
  const instance = component.instance();
  instance.onSearch(event);
  expect(onSearchMock).toBeCalledWith('the-value');
});

해결책을 알아냈어요

그래서, 안에 있는 값을 전달하지 않고InputBox, 우리는 그것을 의 두 번째 매개 변수 안에 전달해야 합니다.simulate아래 그림과 같이그런 다음 에 대한 첫 번째 콜의 첫 번째 arg와 동등함을 체크합니다.mockFn또한, 우리는 이 모든 것을 없앨 수 있다.event.preventDefault();

it("onChange param is the same value as the input element's value property", () => {
    const mockFn = jest.fn();
    const input = enzyme.shallow(<InputBox 
                                    value=""
                                    placeholder="" 
                                    className="" 
                                    onSearch={mockFn}/>);

    input.find('input').simulate('change', {target: {value: 'matched'} });
    expect(mockFn.mock.calls[0][0]).toBe('matched');
});

이것은 어떠세요?효소를 사용하여 변화 이벤트를 시뮬레이션하고 스냅숏 테스트를 실시합니다.요소

import React, { FunctionComponent, useState } from 'react';

const Index: FunctionComponent = () => {

  const [val, setVal] = useState('');

  const onInputChange = e => {
    e.preventDefault();
    setVal(e.target.value);
  };

  return (
    <input type='text' onChange={onInputChange} value={val} />
  );
};

export default Index;

유닛 테스트

describe('Index with enzyme', () => {
  it('Should set value to state when input is changed', () => {
    const container = shallow(<Index />);
    const input = container.find('input');
    input.simulate('change', { preventDefault: jest.fn, target: { value: "foo" } });
    expect(container).toMatchSnapshot();
  });
});

스냅숏

exports[`Index with enzyme Should set value to state when input is changed 1`] = `
  <input
    onChange={[Function]}
    type="text"
    value="foo"
  />
`;

난 몇 시간 동안 이것과 씨름했어.또한 한 페이지에 여러 개의 선택 필드가 있었기 때문에제가 발견한 것은 텍스트필드 솔루션은 문서에서 제공되는 Select.test와는 다르게 동작한다는 것입니다.

코드에서 ID를 사용하여 Select Props를 정의했습니다.(데이터 테스트 ID를 사용할 수도 있습니다)

이 필드를 클릭해야만 드롭다운을 트리거할 수 있습니다.

<TextField
  select
  variant = "outlined"
  value = { input.value || Number(0) }
  onChange = { value => input.onChange(value) }
  error = { Boolean(meta.touched && meta.error) }
  open = { open }
  SelectProps = {
    {
      id: `${input.name}-select`,
      MenuProps: {
        anchorOrigin: {
          vertical: "bottom",
          horizontal: "left"
        },
        transformOrigin: {
          vertical: "top",
          horizontal: "left"
        },
        getContentAnchorEl: null
      }
    }
  } 
  { ...props} >

  //yourOptions Goes here

 </TextField>

그리고 내 시험에서도.

const pickUpAddress = document.getElementById("address-select");

UserEvent.click(pickUpAddress);
UserEvent.click(screen.getByTestId("address-select-option-0"));

그 후엔 마법처럼 작동했지이게 도움이 됐으면 좋겠다.

lwc(salesforce) 재스트 테스트를 작성할 경우 입력을 선택하고 이벤트를 디스패치하여 시뮬레이트할 수 있습니다.

const changeEvent = new CustomEvent('change', {
        detail: {
            'value': 'bad name'
        }
    });

element.shadowRoot.querySelector('lightning-input').dispatchEvent(changeEvent);

언급URL : https://stackoverflow.com/questions/48180499/testing-onchange-function-in-jest

반응형