Почему порядок этих функций имеет значение в этом шутливом тесте? - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть следующий компонент ...

export default class TextInput extends PureComponent<TextInputProps> {

  private handleOnChange = (event: OnChangeEvent): void => {
    if (!this.props.disabled && this.props.onChange) {
      this.props.onChange(event)
    }
  }

  private handleOnBlur = (event: OnBlurEvent): void => {
    if (!this.props.disabled && this.props.onBlur) {
      this.props.onBlur(event)
    }
  }

  public render(): ReactNode {
    return (
      <Styled.TextInput
        id={this.props.id}
        type={this.props.type}
        onChange={this.handleOnChange}
        onBlur={this.handleOnBlur}
        disabled={this.props.disabled}
      />
    )
  }
}

И я пытаюсь проверить функцию handleOnChange, используя следующий тест ...


const mockOnChange = jest.fn((): void => { })
const mockOnBlur = jest.fn((): void => { })

const minHandlerProps ={
  id: 'test',
  type: 'text',
  onChange: mockOnChange,
  onBlur: mockOnBlur,
}

describe('handleOnChange', () => {
  it('Should not call the onChange prop when it\'s been passed and TextInput is disabled', () => {
    const wrapper = shallow(<TextInput {...minHandlerProps} disabled={true} />)
    const instance = wrapper.instance()

    instance.handleOnChange()
    expect(minHandlerProps.onChange).not.toHaveBeenCalled()
  })

  it('Should call the onChange prop when it\'s been passed and TextInput is not disabled', () => {
    const wrapper = shallow(<TextInput {...minHandlerProps} />)
    const instance = wrapper.instance()

    instance.handleOnChange()
    expect(minHandlerProps.onChange).toHaveBeenCalled()
  })
})

Тесты проходят, когда они в этом порядке, но если я поменяю местами порядок , не следует вызывать тест onChange prop . Сбой.

Это потому, что в этом случае в первый раз уже вызывался onChange prop Это()?

Должен ли я написать отдельное описание для этого?

Я записал в консоль, что реквизиты проходят правильно, и похоже, что они есть, так что я в растерянности, так как к этому поведению. Спасибо всем, кто может пролить свет на это.

1 Ответ

0 голосов
/ 27 апреля 2020

Определяя фиктивные функции вне блока описания, вы разделяете один экземпляр каждого из всех тестов. Это означает, что вы видите вызовы из других тестов, поэтому ваш тест зависит от порядка ( очень плохая вещь для модульных тестов).

Для этого есть различные решения:

  1. Создайте новый экземпляр для каждого теста, например, в beforeEach:

    describe('handleOnChange', () => {
      let minHandlerProps;
      let mockOnBlur;
      let mockOnChange;
    
      beforeEach(() => {
        mockOnChange = jest.fn((): void => { })
        mockOnBlur = jest.fn((): void => { })
    
        minHandlerProps = {
          id: 'test',
          type: 'text',
          onChange: mockOnChange,
          onBlur: mockOnBlur,
        }
      });
    
      ...
    });
    
  2. Сбросьте каждый явно между тестами с помощью mockClear :

    describe('handleOnChange', () => {       
      beforeEach(() => {
        mockOnBlur.mockClear();
        mockOnChange.mockClear();
      });
    
      ...
    });
    
  3. Сбросить все ложные показания между тестами с помощью clearAllMocks:

    describe('handleOnChange', () => {       
      beforeEach(() => {
        jest.clearAllMocks();
      });
    
      ...
    });
    
  4. Получить Jest для сброса всех макетов между тестами, установив clearMocks в true в вашей конфигурации.


В качестве примечания, я не рекомендует проверить, что при вызове handleOnChange в экземпляре запускается поддельная функция prop. Это реализация - поведение компонента заключается в том, что обратный вызов вызывается при изменении Styled.TextInput, или, что еще лучше, когда происходит какое-либо взаимодействие с , что происходит компонента , Симуляция этих событий оставляет вас менее привязанными к вашей текущей реализации.

...