Reactjs тестирование условного рендеринга (снимок)
Я пытаюсь протестировать свое приложение ReactJS, но у меня есть проблема. У меня есть заголовок, который определенным образом отображается для первой страницы приложения, и этот заголовок изменится на всех других страницах. Я управляю изменениями, используя текущее местоположение из react-router-dom
, Я не знаю, как проверить, что в зависимости от URL, заголовок меняется. Прямо сейчас я делаю основные вещи в моем тестовом файле:
import React from 'react';
import { shallow } from 'enzyme';
import HeaderSto from './HeaderSto';
import '../../setupTests';
describe("HeaderSto", () => {
it("should render my component", () => {
process.env.REACT_APP_MERCHANT = "merchant";
const wrapper = shallow(<HeaderSto />);
expect.anything(wrapper);
});
it("should render LandingPage header layout", () => {
process.env.REACT_APP_MERCHANT = "merchant";
window.location.assign = jest.fn();
const tree = shallow(<HeaderSto />);
expect(tree).toMatchSnapshot();
});
});
И компонент
import React from 'react';
import { Row, Col } from 'antd';
class HeaderSto extends React.Component {
constructor(props) {
super(props);
this.state = {
CurrentRoute: ""
};
}
componentDidMount() {
this.setState({
CurrentRoute: this.props.CurrentRoute
});
}
componentWillReceiveProps(nextProps) {
this.setState({
CurrentRoute: nextProps["CurrentRoute"]
});
}
renderGeneralHeader() {
return(<div>Hi</div>);
}
renderLandingPageHeader() {
const logo = require("../../images/" + process.env.REACT_APP_MERCHANT + "/" + process.env.REACT_APP_MERCHANT + "_logo.svg");
return (
<div>
<Row>
<Col className="header-merchant-logo-div" xs={{span: 18, offset: 3}} sm={{span: 18, offset: 3}} md={{span: 18, offset: 3}} lg={{span:4, offset: 1}} xl={{span:4, offset: 1}}>
<img className="header-merchant-logo" src={logo} alt="MerchantLogo"/>
</Col>
</Row>
</div>
);
}
render() {
return (
<div>
{this.state.CurrentRoute === "/" ? this.renderLandingPageHeader() : this.renderGeneralHeader()}
</div>
);
}
}
export default HeaderSto;
Я должен смоделировать местоположение (это должно быть легко), но я не понимаю, как я должен указать, чтобы шутить, что снимок не совпадает в зависимости от этого места...
Я думаю, что я все объяснил, не стесняйтесь спрашивать больше деталей, если это необходимо.
Спасибо за помощь. Хорошего дня
2 ответа
Привет, Ульд. Я ценю, если вы изучаете юнит-тестирование согласно своей цели. Помните, что в Jest есть два типа тестирования SnapShot и тестирование поведения компонентов. Мы проводим тестирование моментальных снимков, например, "Как мы структурируем наш компонент". Если вносить какие-либо изменения в структуру jsx, он не должен совпадать с предыдущим снимком, если он есть.
В вашем случае есть две ветви в вашем HeaderSto
если вы видите свой отчет о покрытии. Вы должны убедиться, что вы тестируете оба случая, чтобы обеспечить 100% охват. Проходя "/" один раз, а другой раз - другой маршрут, чтобы выполнить оба условия.
Вот как мы проводим тестирование снимков:
import renderer from 'react-test-renderer';
it('renders correctly', () => {
const tree = renderer.create(
<HeaderSto />
).toJSON();
expect(tree).toMatchSnapshot();
});
РЕДАКТИРОВАНИЕ Давайте рассмотрим пример, позволяющий отличить стратегию моментальных снимков от тестов с мелкой и монтировкой.
У нас есть компонент приложения:
class App extends Component {
render() {
return (
<div className="App">
<Header />
<p className="App-intro" onClick={this.handleClick}>
{data.appName}.
</p>
</div>
);
}
}
ТестированиеSnapShot приведет к этому:
exports[`renders without crashing 1`] = `
<div
className="App"
>
<Header />
<p
className="App-intro"
onClick={[Function]}
>
To get started, edit
<code>
src/App.js
</code>
and save to reload.
</p>
</div>
`;
и мелкий рендеринг расскажет нам, как ведет себя наш компонент: мы будем имитировать data.appName и метод onClick, так как наше приложение ожидает одно свойство appName, а также нам нужно протестировать его дескриптор, поэтому мы имитируем их обоих:
const data = {
appName: 'My App'
}
describe('HandleClick on P event success', () => {
it('handleClick click invokes without throwing an error', () => {
const handleClick = jest.fn();
const wrapper = shallow(<App
handleClick={handleClick}
/>);
wrapper.find('.app').simulate('click');
expect(handleClick).toHaveBeenCalled();
});
});
Не стесняйтесь делиться любыми мыслями. Рад помочь вам с этим.
Я не вижу, где вы используете функцию определения местоположения, похоже, CurrentRoute
только что прошел через реквизит. Так что просто передайте это в ваших тестах так:
it("should render LandingPage header layout", () => {
process.env.REACT_APP_MERCHANT = "merchant";
const tree = shallow(<HeaderSto />);
expect(tree).toMatchSnapshot();
});
it("should render LandingPage header layout", () => {
process.env.REACT_APP_MERCHANT = "merchant";
const tree = shallow(<HeaderSto currentRoute="/some-other-path" />);
expect(tree).toMatchSnapshot();
});