admin管理员组文章数量:1384579
I'm trying to do unit testing to a ponent using enzyme shallow rendering. Trying to test state activeTab of the ponent and it throws TypeError: Cannot read property state
. my ponent Accordion. Accordion ponent jsx code
class Accordion extends Component {
constructor(props) {
super(props)
this.state = {
activeTab: 0
}
}
static defaultProps = {
tabs: [{title: 'Status'}, {title: 'Movement'}]
}
render() {
const { tabs } = this.props
, { activeTab } = this.state
return (
<div className={`accordion`}>
{tabs.map((t, i) => {
const activeClass = activeTab === i ? `accordion--tab__active` : ''
return(
<section key={i} className={`accordion--tab ${activeClass}`}>
<header className={`accordion--header`}>
<h4 className={`accordion--title`}>
<button onClick={() => {this._selectAccordion(i)}}>{t.title}</button>
</h4>
</header>
<div className="accordion--content">
{t.title}
Content
</div>
</section>
)
})}
</div>
)
}
_selectAccordion = activeTab => {this.setState({activeTab})}
}
export default Accordion
and Accordion.react.test.js
import { shallow } from 'enzyme'
import Accordion from './ponents/Accordion'
test('Accordion ponent', () => {
const ponent = shallow(<Accordion name={`Main`}/>)
expect(ponent.state('activeTab')).equals(0)
})
I'm trying to do unit testing to a ponent using enzyme shallow rendering. Trying to test state activeTab of the ponent and it throws TypeError: Cannot read property state
. my ponent Accordion. Accordion ponent jsx code
class Accordion extends Component {
constructor(props) {
super(props)
this.state = {
activeTab: 0
}
}
static defaultProps = {
tabs: [{title: 'Status'}, {title: 'Movement'}]
}
render() {
const { tabs } = this.props
, { activeTab } = this.state
return (
<div className={`accordion`}>
{tabs.map((t, i) => {
const activeClass = activeTab === i ? `accordion--tab__active` : ''
return(
<section key={i} className={`accordion--tab ${activeClass}`}>
<header className={`accordion--header`}>
<h4 className={`accordion--title`}>
<button onClick={() => {this._selectAccordion(i)}}>{t.title}</button>
</h4>
</header>
<div className="accordion--content">
{t.title}
Content
</div>
</section>
)
})}
</div>
)
}
_selectAccordion = activeTab => {this.setState({activeTab})}
}
export default Accordion
and Accordion.react.test.js
import { shallow } from 'enzyme'
import Accordion from './ponents/Accordion'
test('Accordion ponent', () => {
const ponent = shallow(<Accordion name={`Main`}/>)
expect(ponent.state('activeTab')).equals(0)
})
Share
Improve this question
edited Oct 4, 2017 at 11:32
Wimal Weerawansa
asked Sep 25, 2017 at 10:24
Wimal WeerawansaWimal Weerawansa
1572 gold badges16 silver badges35 bronze badges
6
-
2
The test runs well on my puter, though I have to change
.equals(0)
to.toEqual(0)
. Maybe you could share more debugging information, like enzyme/node version, or at least paste the full error message - the one you pasted surely is only half the message. – AVAVT Commented Sep 30, 2017 at 20:29 - Did you import REACT in Jsx file? – user7159290 Commented Oct 3, 2017 at 10:32
-
Yes I import React in
jsx
file. – Wimal Weerawansa Commented Oct 3, 2017 at 11:09 -
You say
jsx
file, but in Accordian.react.test.js you doimport Accordion from './ponents/Accordion.js
, which is ajs
file not ajsx
file. Are you sure the file extension is correct? You shouldn't need to put the file extension in the file path anyway. – daphtdazz Commented Oct 3, 2017 at 20:53 -
Its a mistake i have fixed it, but on my real project its just
Accordion
– Wimal Weerawansa Commented Oct 4, 2017 at 11:33
2 Answers
Reset to default 3This could be a this scoping issue. With event handlers in React, you have to bind the event handler in the constructor to "this". Here is some info from React's docs about it:
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method.
class Accordion extends Component {
constructor(props) {
super(props)
this.state = {
activeTab: 0
}
// This binding is necessary to make `this` work in the callback
this._selectAccordion = this._selectAccordion.bind(this);
}
static defaultProps = {
tabs: [{title: 'Status'}, {title: 'Movement'}]
}
_selectAccordion(activeTab){
this.setState({activeTab : activeTab})
}
render() {
const { tabs } = this.props,
{ activeTab } = this.state
return (
<div className={`accordion`}>
{tabs.map((t, i) => {
const activeClass = activeTab === i ? `accordion--tab__active` : ''
return(
<section key={i} className={`accordion--tab ${activeClass}`}>
<header className={`accordion--header`}>
<h4 className={`accordion--title`}>
<button onClick={() => {this._selectAccordion(i)}}>{t.title}</button>
</h4>
</header>
<div className="accordion--content">
{t.title}
Content
</div>
</section>
)
})}
</div>
)
}
}
Your tests should verify how the ponent works but not "how to change a state". You need to throw new props into your ponent and get a result, and the result is expected.
I've tested my ponents with snapshots
This is an example of my current project
describe('<Component />', () => {
it('Page rendered', () => {
const rendered = renderComponent({
...testProps,
loadDataList,
loading: true,
});
expect(rendered).toMatchSnapshot();
});
});
本文标签: javascriptReact test with enzyme TypeError Cannot read property 39state39 of undefinedStack Overflow
版权声明:本文标题:javascript - React test with enzyme TypeError: Cannot read property 'state' of undefined - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744537897a2611426.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论