Как писать тесты для компонента, который использует пользовательский интерфейс материалов компонентов таблицы?

#reactjs #testing #enzyme

#reactjs #тестирование #фермент

Вопрос:

У меня много проблем с написанием теста для следующего кода:

 import { Table, TableBody, TableCell, TableHead, TableRow, Tooltip } from '@material-ui/core';
import React, { Component } from 'react';

const Status = ({ id, dependency}) => {

  let text, tooltipText;

  if (id === 'something' ) {
    tooltipText = `Some helpful text.`;
    text = "undefined";
  } else if (id === 'other' ) {
    tooltipText = `Some other helpful text.`;
    text = "undefined";
  } else{
    tooltipText = `Unknown`;
    text = "unknown";
  } 
  return (
    <Tooltip title={tooltipText} >
        <span>
          {text}
        </span>
    </Tooltip>
  );
};

class StatusList extends Component {

  render() {
    const { cardTitle, dependencies, id } = this.props;

    if (!dependencies) {
      return null;
    }

    return (
      <Card title={cardTitle}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>ID</TableCell>
              <TableCell>STATUS</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {dependencies.map(dep => (
              <TableRow key={dep.id}>
                <TableCell>
                  <URL to={`/${dep.id}`}>{dep.id}</URL>
                </TableCell>
                <TableCell>
                  <Status id={id} dependency={dep} />
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </Card>
      );
   }
};
  

Пока у меня есть следующие тесты:

 import { shallow } from 'enzyme';

describe('test', () => {
const props = {
    cardTitle: "Dependencies",
    dependencies: [id: 'something'],
    id: 'my-id'
};
it('renders', () => {
    const wrapper = shallow(<Status {...props} />);
    expect(wrapper.find(TableBody).find(TableRow)).toHaveLength(4);
  });
}); 
  

Который работает нормально, но теперь я хочу утверждать, что отображается Status функцией — т. Е. Я хочу проверить логику там и убедиться, что отображается правильное tooltipText . Я попытался написать следующий тест:

 it('renders row with expected status', () => {
    const wrapper = shallow(<StatusList {...props} />);
    expect(wrapper.find(Table).find(TableBody).find(TableRow).first().find(TableCell).find('Tooltip').props.title).toEqual('Some helpful text.');
  });
  

но я получаю сообщение об ошибке:

Ожидаемое значение равно: «Некоторый полезный текст». Получено: не определено

и я не уверен, что я делаю неправильно..

Ответ №1:

При использовании enzyme shallow() для рендеринга компонента отображается только первый уровень, что означает, что вывод первого уровня будет содержать <Status /> компонент, но не какие-либо дочерние элементы этого компонента.

Чтобы иметь возможность делать утверждения о Status дочерних элементах, мы должны сделать один уровень глубже, а затем сделать утверждения:

 it('renders row with expected status', () => {
    const wrapper = shallow(<StatusList {...props} />);
    const firstTableRow = wrapper.find(Table).find(TableBody).find(TableRow).first();
    const tableCell = firstTableRow.find(TableCell);
    const status = tableCell.find('Status');

    const statusWrapper = status.shallow(); // now we can dive into children!
    const tooltip = statusWrapper.find(Tooltip);

    expect(tooltip.props().title).toEqual('Some helpful text.');
});
  

Также не забудьте использовать .props().propName вместо .props.propName , поскольку .props() это функция, а не свойство оболочки.

Смотрите этот упрощенный codesandbox, содержащий тесты ферментов для аналогичного компонента.