Reactjs 使用'的浅层误差进行酶基础试验;目标不是DOM元素';

Reactjs 使用'的浅层误差进行酶基础试验;目标不是DOM元素';,reactjs,enzyme,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 | } &

我正在使用
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)
我相信我正在使用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))
类LogoButton扩展React.Component{
handleReset=async()=>{
history.push(“/”)
this.props.setUIElementStatus({
uiElement:UI\u ELEMENTS.UI\u搜索栏,显示:false
})
this.props.setSearchInputValue({text:'})
}
render(){
const{titleFilled,titleBlank}=this.props.classes
const titleClass=this.props.uiStatus.searchBar?titleFilled:titleBlank
常量navButtonProps={
onClick:this.handleReset,
类名:标题类,
变体:“flat”作为“flat”,
disableFocusRipple:对,
真的吗
}
返回(
Tansaki
)
}
}
常量mapStateToProps=(状态:storeTypes.Store)=>{
const{uiStatus}=状态
返回{uiStatus}
}
常量{setSearchInputValue}=InputActions
常量{setUIElementStatus}=UiActions
常量mapDispatchToProps={setSearchInputValue,setUIElementStatus}
导出默认样式(样式)(连接(
mapStateToProps,mapDispatchToProps
)(按钮)
问题 该错误意味着
index.tsx
被意外导入
LogoButton.test.tsx

解决方案 追溯从
LogoButton.test.tsx
开始的
import
语句,直到找到意外导入
index.tsx
的位置,并修复或删除该
import
语句

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


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

能否提供LogoButton的代码?似乎出于某种原因,ReactDOM.render代码正在被调用-该代码不可能被调用。@flq已更新。我取出了所有的导入、材质ui样式和类型脚本接口/类型。它感觉像是一个完全正常的组件。尝试导出未连接的LogoButton,并将其用于测试-它是否仍有异常行为?@flq完全是我的错。正如brian在回答中所说,我在
index.tsx中创建和导出我的
历史记录
,这就是问题的根源。我在
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()
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))