Как проверить функцию ReactJS, которая использует хуки и не возвращает JSX - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь разобраться в функциональном тестировании в React, и я наткнулся на блокиратор, с которым я sh мог бы пролить свет. В настоящее время у меня есть небольшое приложение-счетчик, в котором есть компонент кнопки, который получает функцию и строку в качестве реквизита. это выглядит так:

Кнопка. js

import React from 'react'
import PropTypes from 'prop-types'

export const Button = (props) => {
  const { btnTitle, btnAction } = props

  return (
    <button onClick={btnAction}>{btnTitle}</button>
  )
}

Button.propTypes = {
  btnAction: PropTypes.func,
  btnTitle: PropTypes.string
}

У меня также есть каталог помощников, который содержит мою функцию CounterHandler, которая получает число в качестве начального значения счетчика значение и может увеличивать или уменьшать указанное начальное значение. Код выглядит следующим образом:

CounterHandler. js

import React from 'react'

export const CounterHandler = num => {
  const [counter, setCounter] = React.useState(num)
  const increase = () => setCounter(counter + 1)
  const decrease = () => setCounter(counter - 1)

  return {
    counter,
    increase,
    decrease
  }
}

Теперь мое приложение. js, которое отображает кнопку и код действия выглядит следующим образом .

Приложение. js

import React from 'react'
import CounterHandler from './components/button/helpers'
import Button from './components/button'

function App () {
  const counter = CounterHandler(0)

  return (
    <div className="App">
      <Button btnTitle="click to increase" btnAction={counter.increase} />
      <Button btnTitle="click to decrease" btnAction={counter.decrease} />
      <h1>counter: {counter.counter}</h1>
    </div>
  )
}

export default App

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

Сейчас я пытаюсь написать тест для моей функции CounterHandler. js, но, к сожалению, я продолжаю сталкиваться с ошибкой перехвата, которая не возникает при запуске приложения на моем локальном компьютере. server.

Пока что единственный тест, который я хотел попробовать, это получить начальное значение, найденное в моем счетчике, и продолжить оттуда. Мой тест выглядит так:

CounterHandler.test. js

import { CounterHandler } from './CounterHandler'

const counter = CounterHandler(0)

describe('Counter state', () => {
  test('test initial state', () => {
    expect(counter.counter).tobe(0)
  })
})

и вывод, который я получаю:

enter image description here

Может кто-нибудь дать мне несколько советов? Я буду очень признателен.

для дальнейшего изучения моих конфигов, это мой экспериментальный аккаунт GitHub для этого проекта. https://github.com/melvinalmonte/testing-practice

Спасибо !!

1 Ответ

1 голос
/ 11 февраля 2020

Как показано сообщение об ошибке, перехватчики реакции (useState et c ..) должны вызываться внутри компонента реакции. Но в своем тесте вы назвали его вне компонента реагирования.

Рекомендованный способ проверки этого случая: не проверять пользовательские крючки напрямую, проверить их вместе с реагирующим компонентом.

Например, app.js:

import React from 'react';
import { CounterHandler } from './counterHandler';

function App() {
  const counter = CounterHandler(0);

  return (
    <div className="App">
      <button name="increase" onClick={counter.increase}>
        click to increase
      </button>
      <button name="decrease" onClick={counter.decrease}>
        click to decrease
      </button>
      <h1>counter: {counter.counter}</h1>
    </div>
  );
}

export default App;

counterHandler.js:

import React from 'react';

export const CounterHandler = (num) => {
  const [counter, setCounter] = React.useState(num);
  const increase = () => setCounter(counter + 1);
  const decrease = () => setCounter(counter - 1);

  return {
    counter,
    increase,
    decrease,
  };
};

app.test.js:

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

describe('60158977', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<App></App>);
  });
  it('should render', () => {
    expect(wrapper.find('h1').text()).toBe('counter: 0');
  });

  it('should increase counter', () => {
    wrapper.find('button[name="increase"]').simulate('click');
    expect(wrapper.find('h1').text()).toBe('counter: 1');
  });

  it('should decrease counter', () => {
    wrapper.find('button[name="decrease"]').simulate('click');
    expect(wrapper.find('h1').text()).toBe('counter: -1');
  });
});

Результаты модульных испытаний со 100% покрытием:

 PASS  stackoverflow/60158977/app.test.js
  60158977
    ✓ should render (9ms)
    ✓ should increase counter (3ms)
    ✓ should decrease counter (1ms)

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |     100 |      100 |     100 |     100 |                   
 app.js            |     100 |      100 |     100 |     100 |                   
 counterHandler.js |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        3.884s, estimated 4s

Исходный код: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60158977

...