Ошибка при попытке рендеринга компонента в библиотеке реактивного тестирования - получен объект

Я пытаюсь настроить некоторые интеграционные тесты некоторых компонентов реакции, которые подключены к нашему хранилищу избыточности.

Наш общий шаблон — это константа (вместо компонента), которая «подключена» с избыточностью к хранилищу (я думаю, что это просто предыстория проблемы, поскольку у меня такая же проблема с обычным компонентом).

Я следую https://testing-library.com/docs/example-react-redux

я получаю эту ошибку

   console.error node_modules/react/cjs/react.development.js:172
      Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

  Check your code at feedback.test.js:32.
console.error node_modules/react-dom/cjs/react-dom.development.js:19814
  The above error occurred in the <Provider> component:
      in Provider (at feedback.test.js:26)

это мой тест

import React from 'react';
import {createStore} from 'redux'
import {Provider} from 'react-redux'
import {render, getByTitle, fireEvent} from '@testing-library/react'
//import '@testing-library/cleanup-after-each'
import '@testing-library/jest-dom/extend-expect'

import {FeedbackContainer} from '../feedbackContainer'
import {defaultState, reducer} from '../../../../redux/modules/feedback'

function renderWithRedux(
  component,
  {
    initalState, store = createStore(reducer, defaultState)
  } = {}
) {
  return {
    ...render(<Provider store={store}>{component}</Provider>)
  }
}

it('increments the counter', () => {
  console.log(<FeedbackContainer/>)
  const {container} = renderWithRedux(<FeedbackContainer />) <-- line 32
})

Мой контейнерный компонент выглядит так:

import { connect } from 'react-redux';
import { Feedback } from './feedback';
import { compose, lifecycle, withHandlers } from 'recompose';
import { actions } from '../../../redux/modules/feedback';

export const mapStateToProps = (state, ownProps) => ({
// snipped state maps
});

export const mapDispatchToProps = {
// snipped functions
};

const enhance = compose(
  connect(mapStateToProps, mapDispatchToProps),
  withHandlers({
    sendFeedbackHandler: props => () => props.sendFeedback(props),
    handleResize: props => () => props.setWindowSize(),
  }),
  lifecycle({
    componentDidMount() {
      const {handleResize} = this.props
      window.addEventListener('resize',handleResize);
    },
    componentWillUnmount() {
      this.props.clearFeedback();
      const {handleResize} = this.props
      window.removeEventListener('resize', handleResize);
    },
  }),
);

export const FeedbackContainer = enhance(Feedback);

Feedback.js выглядит так:

import React from 'react';
import ReactStars from 'react-stars';

export const Feedback = (props) => {

    const ratingChanged = (rating) => {
      props.setRating(rating);
    }

    const {sendFeedbackHandler} = props

    var title = null;
    switch (props.type) {
      case "REF":
        title = "Rate this FAQ"
        break;
      default:
        title = "Rate my experience"
        break
    }

    var feebackLayout;
    var buttonClassNames = "btn btn-success btn-cons pull-right";
    if (props.apertureWidth > 768) {
      buttonClassNames += " margin-right-0px ";
      feebackLayout = (
        <div>
          <h5 className="light semi-bold text-center" style={{"margin":"0px"}}>
            {title}
          </h5>
          <div style={{"textAlign":"center"}}>
            <div data-test-id='feedback-stars' className="center" style={{"display":"inline-block","float":"none"}}>
              <ReactStars
                value={props.rating}
                count={5}
                onChange={ratingChanged}
                size={24}
                color2={'#ffd700'}
                half={false}
              />
            </div>
          </div>
        </div>
      )
    } else {
      buttonClassNames += " margin-right-14px ";
      title = "Rate this:"
      feebackLayout = (
        <div style={{"textAlign":"center"}}>
          <h5 className="light semi-bold text-center"
           style={{"margin":"0px","display":"inline","verticalAlign":"middle","paddingRight":"10px"}}>
            {title}
          </h5>
          <div style={{"textAlign":"center","display":"inline-block","verticalAlign":"middle"}}>
            <ReactStars
              value={props.rating}
              count={5}
              onChange={ratingChanged}
              size={24}
              color2={'#ffd700'}
              half={false}
            />
          </div>
        </div>
      )
    }

    return (
      <div className="card card-default feedbackCard" style={{"height": "100%","borderTopRightRadius": "2px", "borderTopLeftRadius": "2px"}}>
        <div className="card-block" style={{padding: '20px 20px 20px 20px'}}>
          <div hidden={props.feedbackSubmitted}>
            {feebackLayout}
            <div hidden={props.feedbackHidden}
             style={{"paddingTop": props.apertureWidth > 768 ? "0px" : "10px"}}>
              <div>
                <textarea
                  data-test-id='feedback-text'
                  className="form-control"
                  style={{"height":"unset"}}
                  placeholder="Add any comments"
                  rows={2}
                  onChange={event => props.setFeedback(event.target.value)}
                />
              </div>
              <div style={{paddingTop: "5px"}}>
                <button
                  data-test-id='feedback-submit'
                  className={buttonClassNames}
                  onClick={sendFeedbackHandler}
                >
                  {props.buttonText}
                </button>
              </div>
            </div>
          </div>
          <div hidden={!props.feedbackSubmitted}>
            <h5 className="light semi-bold text-center">
              {props.feedbackSubmittedMessage}
            </h5>
          </div>
        </div>
      </div>
    )
};

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

Если я console.log компоненты в моем тесте, они оба возвращают объекты из того, что я вижу, поэтому я не совсем понимаю ошибку.

Контейнер обратной связи:

{ '$$typeof': Symbol(react.element),
        type:
         { mapStateToProps: [Function],
           mapDispatchToProps: [Function: mapDispatchToProps],
           reactComponent: { [Function: WithHandlers] displayName: 'withHandlers(lifecycle(Component))' },
           mockDispatch:
            { [Function: mockConstructor]
              _isMockFunction: true,
              getMockImplementation: [Function],
              mock: [Getter/Setter],
              mockClear: [Function],
              mockReset: [Function],
              mockReturnValueOnce: [Function],
              mockReturnValue: [Function],
              mockImplementationOnce: [Function],
              mockImplementation: [Function],
              mockReturnThis: [Function],
              mockRestore: [Function] } },
        key: null,
        ref: null,
        props: {},
        _owner: null,
        _store: {} }

Обратная связь:

{ '$$typeof': Symbol(react.element),
        type: [Function],
        key: null,
        ref: null,
        props: {},
        _owner: null,
        _store: {} }

Из некоторого чтения я думаю, что это может быть связано с некоторыми совместимостью версий, это то, что у меня есть в моем package.json:

"jest": "^21.2.1",
"@testing-library/jest-dom": "^4.1.0",
"@testing-library/react": "^9.1.4",
"react": "^16.8.6",
"react-dom": "^16.0.0",
"react-redux": "^5.0.5",
"redux": "^3.7.2",
"redux-saga": "^0.15.6",

Где я ошибаюсь?!


person mattb    schedule 16.09.2019    source источник
comment
Похоже, Feedback возвращает объект. Может быть, вы можете попробовать отладить его, чтобы понять, почему   -  person Giorgio Polvara - Gpx    schedule 16.09.2019
comment
@mattb, не могли бы вы поделиться исходным кодом и для Feedback?   -  person skovy    schedule 16.09.2019
comment
В следующих версиях ваш код работает для меня: "jest": "^24.7.1", "@testing-library/jest-dom": "^4.1.0", "@testing-library/react": "^9.1.4", "react": "^16.8.6", "react-dom": "^16.8.6", "react-redux": "^7.1.1", "redux": "^4.0.1",   -  person mgarcia    schedule 16.09.2019
comment
@skovy - отредактировал мой пост. Благодарность   -  person mattb    schedule 16.09.2019
comment
Так как @GiorgioPolvara-Gpx предположил, что проблема в том, что я получаю объект, я думаю, что сузил это до моего FeedbackContainer, используя recompose.compose для создания HOC. Могу ли я что-то сделать, чтобы @testing-library/react.render принял это?   -  person mattb    schedule 17.09.2019
comment
RTL не должно заботить то, что вы используете для рендеринга своих компонентов. В конце концов, он просто попросит React отобразить все, что вы передаете, а затем взаимодействовать с результатом. Я думаю, что ваша проблема в компонентах, а не в RTL   -  person Giorgio Polvara - Gpx    schedule 17.09.2019
comment
но если мой компонент может отображаться в браузере, он обязательно должен быть действительным компонентом?   -  person mattb    schedule 18.09.2019