Недопустимый тип элемента - экспорт по умолчанию и импорт по умолчанию - PullRequest
0 голосов
/ 05 февраля 2020

Я пишу тесты для своих компонентов, компоненты прекрасно работают в приложении. Их импорт и использование прекрасно работают, но заставить их работать с react-test-renderer не так хорошо. Например, у меня есть социальный компонент, который читает конфигурацию и выдает ссылки.

. / Components / Social / social. js

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

import config from '../../../content/meta/config'

import GithubIcon from '!svg-react-loader!../../images/svg-icons/github.svg?name=GithubIcon'
import LinkedInIcon from '!svg-react-loader!../../images/svg-icons/linkedin.svg?name=LinkedInIcon'
import TwitterIcon from '!svg-react-loader!../../images/svg-icons/twitter.svg?name=TwitterIcon'
import InstagramIcon from '!svg-react-loader!../../images/svg-icons/instagram.svg?name=InstagramIcon'
import DevIcon from '!svg-react-loader!../../images/svg-icons/dev.svg?name=DevIcon'

const Social = props => {
  const { theme } = props
  const items = config.authorSocialLinks
  const icons = {
    twitter: TwitterIcon,
    github: GithubIcon,
    linkedin: LinkedInIcon,
    instagram: InstagramIcon,
    dev: DevIcon,
  }

  return (
    <React.Fragment>
      <div className="social">
        {items.map(item => {
          const Icon = icons[item.name]
          return (
            <a
              href={item.url}
              key={item.name}
              className="socialLink"
              target="_blank"
              rel="noopener noreferrer"
              title={item.name}
            >
              <Icon className="svg" />
            </a>
          )
        })}
      </div>

      {/* --- STYLES --- */}
      <style jsx global>
        {`
          @media screen and (max-width: 450px) {
            .social {
              width: 95%;
            }
          }
          @media screen and (min-width: 450px) {
            .social {
              width: 40%;
            }
          }
          .social {
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0 auto;
            padding: 20px;

            :global(svg) {
              width: 30px;
              height: 30px;
              transition: all 0.5s;
            }

            &:hover :global(svg) {
              fill: ${theme.color.special.attention};
            }
          }

          .svg path {
            fill: ${theme.color.brand.primary};
          }

          .socialLink {
            margin: 0 auto;
            display: inline-block;
            padding: 1px;
            text-align: center;
          }
        `}
      </style>
    </React.Fragment>
  )
}

Social.propTypes = {
  theme: PropTypes.object.isRequired,
}

export default Social

. / Components / Social / index. js

export { default } from './Social'

В моем тесте я импортирую компонент и рендеринг для тестирования моментальных снимков. Тест:

. / Компоненты / тесты / social.spe c. js

import React from 'react'
import { create } from 'react-test-renderer'
import Social from '../Social'
const theme = require('../../theme/theme.json')

describe('Social Component', () => {
  it('renders correctly', () => {
    const tree = create(<Social theme={theme} />).toJSON()
    expect(tree).toMatchSnapshot()
  })
})

Я получаю ошибку только в моем тесте, а не в приложении.

Недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: undefined. Вероятно, вы забыли экспортировать свой компонент из файла, в котором он определен, или вы перепутали импорт по умолчанию и имена.

Проверьте метод рендеринга Social.

I перепробовал много маленьких твиков безрезультатно.

Ответы [ 3 ]

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

Я думаю, что бегущий тест запутался из-за экспорта по умолчанию в индексе барреля. * Файл 1013 *.

Две вещи, которые нужно попробовать:

Изменить индекс. js на

import Social from './Social'
export {
 social
};

Или

Если вы собираетесь в конечном итоге использовать именованные экспорты, почему бы просто не сделать это с самого начала? Измените Social для экспорта export const Social = props => {...} и в вашем файле индекса export * from './Social

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

При запуске jest вся ваша система сборки не существует - в данном случае webpack. Поэтому импорт, подобный этому '!svg-react-loader!../../images/svg-icons/github.svg?name=GithubIcon', выдаст ошибку (или в вашем случае, возможно, вернет undefined?).

Вам нужно запустить jest в контексте веб-пакета, если вы хотите - https://jestjs.io/docs/en/webpack

0 голосов
/ 05 февраля 2020
export { default as Social } from './Social'

Можете ли вы попробовать, как в приведенном выше фрагменте кода?

Я также вижу, что вы пытаетесь неправильно импортировать ваш социальный компонент в social.spe c. js

Разве это не должно быть import Social from '../components/Social'? Вы пытаетесь импортировать его как import Social from '../Social'

...