Как проверить HOC с ферментом, чай - PullRequest
1 голос
/ 05 апреля 2019

У меня есть функция HOC, которая получает компонент React и возвращает компонент реагирования с двумя новыми свойствами метода (handleBack & moveitOnTop), например так:

import React, { Component } from "react";
import classNames from "classnames";

 export default WrappedComponent => {
  return class extends Component {
      constructor(props) {
          super(props);
            this.moveitOnTop = this.moveitOnTop.bind(this);
            this.handleBack = this.handleBack.bind(this);

        this.state = {
            isSearchActive: false
        };
    }
    moveitOnTop(flag) {
        this.setState({ isSearchActive: flag });
        window.scrollTo(0, -100);
    }

    handleBack() {
        this.setState({ isSearchActive: false });
        if (document.body.classList.contains("lock-position")) {
            document.body.classList.remove("lock-position");
        }
    }

    render() {
        const props = {
            ...this.props,
            isSearchActive: this.state.isSearchActive,
            moveitOnTop: this.moveitOnTop,
            goBack: this.handleBack
        };

        const classes = classNames({ "c-ftsOnTop": this.state.isSearchActive });
        return (
            <div className={classes}>
                <WrappedComponent {...props} />
            </div>
        );
    }
  };
 };

Компонент:

 //import fireAnalytics
import { fireAnalytics } from "@modules/js-utils/lib";
class MyComponent extender Component{
  constructor(){
     super(props);
     this.handleClick = this.handleClick.bind(this);
  }

   handleClick(e) {
     // calling analytics function by passing vals
    fireAnalytics({
        event: "GAEvent",
        category: "",
        action: `Clicked on the ${e.target.id} input`,
        label: "Click"
    });

     // I CALL THE HOC PROPERTY
     this.props.moveitOnTop(true);

     // I CALL THE HOC PROPERTY
     this.props.handleBack();
   }

  render(){
     return(
        <div className="emailBlock">
          <input type="text" onClick={handleClick} />
          <Button className="submit">Submit</Button>
        </div>
     )
  }
}

// export HOC component
export default hoc(MyComponent);

// export just MyComponent
export {MyComponent};

Я хочу проверить HOC:

  1. Мне нужно проверить, существует ли класс .c-ftsOnTop
  2. Мне нужно проверить onClick функцию, которая вызывает this.props.handleBack & `this.props.moveitOnTop '
  3. Мне нужно проверить, существует ли className emailBlock.

Тест, который я пробовал, но не прошел:

 import { mount, shallow } from 'enzyme';
 import sinon from 'sinon';
 import React from 'react';
 import { expect } from 'chai';
 import hoc from '....';
 import {MyComponent} from '...';
 import MyComponent from '....';

 it('renders component', () => {

const props = {}
const HocComponent = hoc(MyComponent);
const wrapper = mount(
  <HocComponent {...props} />
);

console.log('wrapper:', wrapper);
expect(wrapper.find('.c-ftsOnTop')).to.have.lengthOf(1);
expect(wrapper.hasClass('c-fts-input-container')).toEqual(true);
 })

Ошибка

AssertionError: expected {} to have a length of 1 but got 0

console.log: wrapper: ReactWrapper {}

Кто-нибудь может мне помочь с тем, как визуализировать HOC?

1 Ответ

0 голосов
/ 05 апреля 2019

Вот рабочий тест:

import { mount } from 'enzyme';
import React from 'react';
import WrappedMyComponent from './MyComponent';

it('renders component', () => {
  const props = {}
  const moveitOnTopSpy = jest.spyOn(WrappedMyComponent.prototype, 'moveitOnTop');
  const handleBackSpy = jest.spyOn(WrappedMyComponent.prototype, 'handleBack');
  const wrapper = mount(
    <WrappedMyComponent {...props} />
  );

  // 1. I need to check that class .c-ftsOnTop exists
  wrapper.setState({ isSearchActive: true });  // <= set isSearchActive to true so .c-ftsOnTop is added
  expect(wrapper.find('.c-ftsOnTop')).toHaveLength(1);  // Success!

  // 2. I need to check onClick function that calls this.props.handleBack & `this.props.moveitOnTop'
  window.scrollTo = jest.fn();  // mock window.scrollTo
  wrapper.find('input').props().onClick();
  expect(moveitOnTopSpy).toHaveBeenCalled();  // Success!
  expect(window.scrollTo).toHaveBeenCalledWith(0, -100);  // Success!
  expect(handleBackSpy).toHaveBeenCalled();  // Success!

  // 3. I need to check if className emailBlock exists
  expect(wrapper.find('.emailBlock')).toHaveLength(1);  // Success!
})

Подробности

.c-ftsOnTop добавляется только тогда, когда isSearchActive равно true, поэтому простоустановите состояние компонента таким образом, чтобы класс был добавлен.

Если вы создаете своих шпионов для методов-прототипов для moveitOnTop и handleBack, то когда hoc создает свои методы экземпляра, связывая их сthis в конструкторе методы экземпляра будут привязаны к вашим шпионам.

window.scrollTo регистрирует ошибку на консоли по умолчанию в jsdom, так что вы можете смоделировать ее, чтобы избежать этого сообщения об ошибке иубедитесь, что он был вызван с ожидаемыми аргументами.


Обратите внимание, что в приведенном выше тесте необходимо исправить следующие опечатки в MyComponent:

  • extender должно бытьextends
  • constructor должен принимать props аргумент
  • onClick должен быть привязан к this.handleClick вместо просто handleClick
  • handleClickследует вызвать this.props.goBack() вместо this.props.handleBack()

(я предполагаю, что MyComponent был просто скомбинирован в качестве примераактуальный компонент)

...