使用“目标不是DOM元素”的浅层错误进行酶基础测试

时间:2018-09-30 20:28:10

标签: reactjs enzyme

我正在尝试使用shallow进行基本测试。我的印象是shallow在组件本身之外需要零依赖关系,但是我遇到了这个错误:

 FAIL  src/test/app/AppHeader/buttons/LogoButton.test.tsx
  ● Test suite failed to run

    Invariant Violation: Target container is not a DOM element.

      16 |   })
      17 | }
    > 18 | 
      19 | ReactDOM.render(
      20 |   <Provider store={store}>
      21 |     <Router history={history}>

      at invariant (node_modules/react-dom/cjs/react-dom.development.js:55:15)

我测试的代码是:

import * as React from 'react'
import { shallow } from 'enzyme'
import LogoButton from 'components/app/AppHeader/buttons/LogoButton'

describe('test of initial load', () => {
    it('test', () => {
        const wrapper = shallow(
            <LogoButton />
        )
        expect(true).toBe(true)
    })
})

和我的index.tsx(错误的位置)是这样的:

import * as React from 'react'
import * as ReactDOM from 'react-dom'
import './index.css'
import registerServiceWorker from 'registerServiceWorker'
import store from 'redux/Store'
import { Provider } from 'react-redux'
import { createHashHistory } from 'history'
import { Router } from 'react-router-dom'
import Root from 'routes/Root'

export const history = createHashHistory()

if (process.env.NODE_ENV !== 'production') {
  Object.defineProperty(window, 'store', {
    get: () => store.getState()
  })
}

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
        <Root />
    </Router>
  </Provider>,
  document.getElementById('root') as HTMLElement
)
registerServiceWorker()

我相信我使用TypeScript的事实与我的问题无关。老实说,我不知道怎么了。从总体上看,我可以理解为什么使用mount会发生这种情况,但是为什么使用shallow呢?为什么此测试会在我的index.tsx中的代码中出现问题?

class LogoButton extends React.Component<Props> {
    handleReset = async () => {
        history.push('/')
        this.props.setUIElementStatus({
            uiElement: UI_ELEMENTS.UI_SEARCH_BAR, show: false
        })
        this.props.setSearchInputValue({ text: '' })
    }

    render() {
        const { titleFilled, titleBlank } = this.props.classes
        const titleClass = this.props.uiStatus.searchBar ? titleFilled : titleBlank
        const navButtonProps = {
            onClick: this.handleReset,
            className: titleClass,
            variant: 'flat' as 'flat',
            disableFocusRipple: true,
            disableRipple: true
        }
        return (
            <Button {...navButtonProps}>
                Tansaki
            </Button>
        )
    }
}

const mapStateToProps = (state: storeTypes.Store) => {
    const { uiStatus } = state
    return { uiStatus }
}

const { setSearchInputValue } = InputActions
const { setUIElementStatus } = UiActions

const mapDispatchToProps = { setSearchInputValue, setUIElementStatus }

export default withStyles(styles)(connect(
    mapStateToProps, mapDispatchToProps
)(LogoButton))

1 个答案:

答案 0 :(得分:2)

问题

该错误意味着index.tsx意外地导入了LogoButton.test.tsx

解决方案

import开始跟踪LogoButton.test.tsx语句,直到发现意外导入index.tsx的位置,然后修复或删除该import语句。

详细信息

如果index.tsx在测试期间被导入,那么它将立即运行ReactDOM.render。在这种情况下,该语句试图将组件呈现到root元素中。

Jest的默认测试环境是jsdom,它提供了类似浏览器的环境,但是document提供的jsdom默认为空,这意味着{{1} }将返回document.getElementById('root')。当null尝试渲染为ReactDOM.render时,它将引发上面看到的错误。