Jest / Enzyme Мелкое тестирование RFC - не стреляет jest.fn () - PullRequest
1 голос
/ 25 мая 2019

Я пытаюсь протестировать пропеллер onChange (и значение) входа в RFC.В тестах при попытке смоделировать событие не запускается функция jest mock.

Фактический компонент подключен (с избыточностью), но я экспортирую его также как неподключенный компонент, так что я могу сделать мелкиймодульный тест.Я также использую некоторые крючки реагирующей пружины для анимации.

Я также пытался смонтировать вместо мелкого компонента, но я все еще получаю ту же проблему.


МОЙ компонент



export const UnconnectedSearchInput: React.FC<INT.IInputProps> = ({ scrolled, getUserInputRequest }): JSX.Element => {

  const [change, setChange] = useState<string>('')


  const handleChange = (e: InputVal): void => {
    setChange(e.target.value)
  }

  const handleKeyUp = (): void => {
    getUserInputRequest(change)
  }

  return (
    <animated.div
      className="search-input"
      data-test="component-search-input"
      style={animateInputContainer}>

      <animated.input
        type="text"
        name="search"
        className="search-input__inp"
        data-test="search-input"
        style={animateInput}
        onChange={handleChange}
        onKeyUp={handleKeyUp}
        value={change}
      />
    </animated.div>
  )
}


export default connect(null, { getUserInputRequest })(UnconnectedSearchInput); 



Мои тесты

Здесь вы можете увидеть тест, который не проходит.Закомментированный код - это другие вещи, которые я безуспешно пробовал до сих пор.



describe('test input and dispatch action', () => {
  let changeValueMock
  let wrapper
  const userInput = 'matrix'

  beforeEach(() => {
    changeValueMock = jest.fn()
    const props = {
      handleChange: changeValueMock
    }

    wrapper = shallow(<UnconnectedSearchInput {...props} />).dive()
    // wrapper = mount(<UnconnectedSearchInput {...props} />)
  })

  test('should update input value', () => {
    const input = findByTestAttr(wrapper, 'search-input').dive()
    // const component = findByTestAttr(wrapper, 'search-input').last()

    expect(input.name()).toBe('input')
    expect(changeValueMock).not.toHaveBeenCalled()

    input.props().onChange({ target: { value: userInput } }) // not geting called
    // input.simulate('change', { target: { value: userInput } })

    // used with mount
    // act(() => {
    //   input.props().onChange({ target: { value: userInput } })
    // })
    // wrapper.update()

    expect(changeValueMock).toBeCalledTimes(1)

    // expect(input.prop('value')).toBe(userInput);
  })
})


Test Error

Ничего особенного здесь нет.

 expect(jest.fn()).toBeCalledTimes(1)

    Expected mock function to have been called one time, but it was called zero times.

      71 |     // wrapper.update()
      72 | 
    > 73 |     expect(changeValueMock).toBeCalledTimes(1)

Любая помощь будет принята с благодарностью, так как прошло уже 2 дня, и я не могу понять это.

1 Ответ

2 голосов
/ 25 мая 2019

вам не нужно взаимодействовать с внутренними компонентами; вместо этого лучше использовать публичный интерфейс: реквизит и результат рендеринга

test('should update input value', () => {
  expect(findByTestAttr(wrapper, 'search-input').dive().props().value).toEqual('');
  findByTestAttr(wrapper, 'search-input').dive().props().onChange({ target: {value: '_test_'} });
  expect(findByTestAttr(wrapper, 'search-input').dive().props().value).toEqual('_test_');
}

Видите, вам не нужно проверять, был ли вызван какой-то внутренний метод, каково его имя или аргумент. Если вы получаете то, что вам нужно - и вам требуется <input> с ожидаемым value - не имеет значения, как это произошло.

Но если функция передается извне (через props), вы определенно захотите проверить, вызывается ли она в каком-то ожидаемом случае

test('should call getUserInputRequest prop on keyUp event', () => {
  const getUserInputRequest = jest.fn();
  const mockedEvent = { target: { key: 'A' } };
  const = wrapper = shallow(<UnconnectedSearchInput getUserInputRequest={getUserInputRequest } />).dive()
  findByTestAttr(wrapper, 'search-input').dive().props().onKeyUp(mockedEvent)
  expect(getUserInputRequest).toHaveBeenCalledTimes(1);
  expect(getUserInputRequest).toHaveBeenCalledWith(mockedEvent);
}

[UPD] выглядит как кеширующий селектор в промежуточной переменной, например

const input = findByTestAttr(wrapper, 'search-input').dive();
input.props().onChange({ target: {value: '_test_'} });
expect(input.props().value).toEqual('_test_');

не проходит, поскольку input относится к устаревшему старому объекту, где value не обновляется.

На ферментном github мне ответили , что это ожидаемое поведение:

Это предполагаемое поведение в ферменте v3 - см. https://github.com/airbnb/enzyme/blob/master/docs/guides/migration-from-2-to-3.md#calling-props-after-a-state-change.

Так что да, именно так - все должно быть заново найдено из корня, если что-то изменилось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...