Reputation: 3272
I'm currently writing tests for my Song
component. The code works as expected in the browser, however, it's breaking in my tests.
Although I've figured out what the issue is and a bad workaround, I don't understand exactly what the problem is and why my solution works.
The Song
component imports AlbumArtContainer
and AvatarContainer
:
import AirbnbPropTypes from 'airbnb-prop-types'
import PropTypes from 'prop-types'
import React from 'react'
import './_styles/Song.scss'
import { ListGroupItemLink } from 'Desktop/components/common'
import { Action, ActionList } from 'Desktop/components/common/actions'
import {
AlbumArtContainer,
ArtistContainer } from 'Desktop/containers/common/music'
export default class Song extends React.Component {
// ... redacted code
}
I have a SongContainer
component inside the same directory as AlbumArtContainer
and AvatarContainer
:
import { connect } from 'react-redux'
import { songs } from 'Common/api'
import { Song } from 'Desktop/components/common/music'
const mapStateToProps = (state, { id }) => {
// ... redacted code
}
const SongContainer = connect(mapStateToProps)(Song)
export default SongContainer
Inside that directory, I have an index.js
file to export everything:
export AlbumArtContainer from './AlbumArtContainer'
export ArtistContainer from './ArtistContainer'
export SongContainer from './SongContainer'
Song.test.jsx
imports Song
:
import Action from 'Desktop/components/common/actions/Action'
import Song from 'Desktop/components/common/music/Song'
describe("<Song>", () => {
// ... redacted tests
})
Running the test for this file throws the following error:
-> % npm run test client/src/Desktop/components/common/music/__tests__/Song.test.jsx
> @ test /home/mightyspaj/Dev/Projects/vibite/client
> jest "client/src/Desktop/components/common/music/__tests__/Song.test.jsx"
FAIL src/Desktop/components/common/music/__tests__/Song.test.jsx
● Test suite failed to run
Invariant Violation: You must pass a component to the function returned by connect. Instead received undefined
at invariant (node_modules/invariant/invariant.js:42:15)
at wrapWithConnect (node_modules/react-redux/lib/components/connectAdvanced.js:101:29)
at Object.<anonymous> (src/Desktop/containers/common/music/SongContainer.jsx:19:62)
at Object.<anonymous> (src/Desktop/containers/common/music/index.js:1:521)
at Object.<anonymous> (src/Desktop/components/common/music/Song.jsx:8:14)
at Object.<anonymous> (src/Desktop/components/common/music/__tests__/Song.test.jsx:2:13)
at next (native)
at next (native)
at process._tickCallback (internal/process/next_tick.js:109:7)
This is because it's reading SongContainer
, and Song
is being imported as undefined
inside SongContainer
. This means that connect()
throws an error when Song
is passed to it because it expects a component.
But if I import AlbumArtContainer
and AvatarContainer
inside SongContainer
directly from their files instead of their module:
import AlbumArtContainer from 'Desktop/containers/common/music/AlbumArtContainer'
import ArtistContainer from 'Desktop/containers/common/music/ArtistContainer'
Then Song
imports correctly inside SongContainer
and it works just fine. I'm not sure why this is, or why it works fine in the browser but not my tests, so what exactly is the issue here?
I also don't want to import components directly from their file (which is why I import them from their module), so my current solution is only a workaround.
Upvotes: 0
Views: 521
Reputation: 3272
From further investigation I realised the issue was due to circular dependencies.
Although it wasn't the solution I'd initially wanted, I've removed the index.js
files, and have also changed my imports to import components directly from their files using default imports.
This has prevented circular dependencies.
Upvotes: 0