enzyme error:“方法'setstate'仅应在单个节点上运行找到了3个”-pg电子游戏官网

热度:11℃ 发布时间:2023-02-26 23:26:36
(adsbygoogle = window.adsbygoogle || []).push({});

如何解决enzyme error:“方法'setstate'仅应在单个节点上运行找到了3个”?

wrapper.update()不应该在那里。它不会返回承诺,也不能被await编辑。默认情况下,酶已经运行了生命周期挂钩,包括componentdidmount。

这个问题是componentdidmount不可测试的,并且不能兑现承诺。应该将其提取为返回可以链接的promise的方法:

loadsomething() { const candidateid = this.props.match.params.candidate_id; return promise.all([ this.props.expressapi.applicationsofcandidate(candidateid), this.props.expressapi.candidatereviewstatus(candidateid), ]).then((data) => { const candidateinfo = data[0][this.props.match.params.candidate_id]; const reviewinfo = data[1][0]; this.setstate({ ... }); }).catch((err) => { this.props.handleerror(err); this.setstate({ error: err, }); });}componentdidmount() { this.loadsomething();}

然后可以将其存入一个测试中:

jest.stub(candidate.prototype, ’loadsomething’)shallow();expect(shallow.instance().loadsomething).tohavebeencalledtimes(1);

并直接在另一个中进行测试:

shallow(, { disablelifecyclemethods: true });await shallow.instance().loadsomething();expect(shallow.state(...))...

解决方法

我对使用react应用程序上的酶/ jest进行测试还很陌生,所以我设置测试的方式可能有些问题。

我特别想在组件中测试一个功能: reviewcandidate()

reviewcandidate() { const { candidate_id: candidateid,} = this.props.match.params; const { latest_application_id: latestapplication,} = this.state.candidateinfo; const { expressapi,} = this.props; /** @todo define user when authentication is in place */ const user = ’undefined’; expressapi.addreviewedcandidate( parseint(candidateid,10),latestapplication,user,// comment,).then(() => { // if the api call is successful,have the state reflect this accordingly this.setstate({ reviewinfo: { candidate_id: candidateid,last_application_reviewed: latestapplication,// comment: comment },}); // pop-up a snackbar indicating a successful review this.props.setsnackbar({ open: true,message: candidate_{candidateid} marked as reviewed,}); });}

使用web应用程序时,它可以正常工作而不会发出任何警告。当我尝试使用jest / enzyme测试它时,就会出现问题。

这是我为上述功能编写的测试:

describe(’reviewing candidates’,() => { const mockcandidatereviewstatus = []; const mockapplicationsofcandidate = {/* mock data */}; const mockexpressapi = { applicationsofcandidate() { return new promise(resolve => resolve(mockapplicationsofcandidate)); },candidatereviewstatus() { return new promise(resolve => resolve(mockcandidatereviewstatus)); },addreviewedcandidate() { return new promise(resolve => resolve()); },}; const handleerror = error => error; it(’ensures reviewedcandidates() is called correctly’,async() => { const setsnackbar = jest.fn(() => ’foobar’); const wrapper = shallow( ); /** * these wrapper.update() calls ensure componentdidmount() finish setting * the state of the component * * unsure if this is the best way to deal with waiting for * componentdidmount() to finish */ await wrapper.update(); await wrapper.update(); await wrapper.instance().reviewcandidate(); /** * @todo: check this.state.reviewinfo is set as expected */ expect(setsnackbar).tohavebeencalled(); });});

但是await wrapper.instance().reviewcandidate()通话使酶崩溃。

error: method “setstate” is only meant to be run on a single node. 3 found instead. at shallowwrapper.single (/path/to/project/node_modules/enzyme/build/shallowwrapper.js:1828:17) at shallowwrapper.setstate (/path/to/project/node_modules/enzyme/build/shallowwrapper.js:575:14) at candidate.shallowwrapper.instance.setstate (/path/to/project/node_modules/enzyme/build/shallowwrapper.js:217:35) at expressapi.addreviewedcandidate.then (/path/to/project/src/components/candidate.js:514:12) at at process._tickcallback (internal/process/next_tick.js:188:7)

如果我注释掉this.setstate调用的.then()api调用后:

reviewcandidate() { // ... expressapi.addreviewedcandidate( // ... ).then(() => { // if the api call is successful,have the state reflect this accordingly /* this.setstate({ reviewinfo: { candidate_id: candidateid,}); */ // pop-up a snackbar indicating a successful review this.props.setsnackbar({ open: true,}); });}

然后测试可以正常进行:

pass test/candidate.test.js (15.954s) pass test/main.test.jstest suites: 2 passed,2 totaltests: 17 passed,17 totalsnapshots: 0 totaltime: 20.378sran all test suites related to changed files.----------------------------|----------|----------|----------|----------|-------------------|file | % stmts | % branch | % funcs | % lines | uncovered line #s |----------------------------|----------|----------|----------|----------|-------------------|all files | 31.05 | 24.58 | 23.04 | 31.88 | | src | 0 | 0 | 0 | 0 | | index.js | 0 | 0 | 0 | 0 | 1,2,3,4,5,6,7,9 | src/components | 43.93 | 38.41 | 33.86 | 44.92 | | candidate.js | 62.41 | 60.87 | 50 | 62.59 |... 88,489,492,616 | main.js | 92.31 | 88.89 | 79.31 | 92.21 |... 34,342,354,363 |----------------------------|----------|----------|----------|----------|-------------------|

万一有关系,这里是componentdidmount()在测试中调用mock api调用的同一组件中的函数:

componentdidmount() { const candidateid = this.props.match.params.candidate_id; promise.all([ this.props.expressapi.applicationsofcandidate(candidateid),this.props.expressapi.candidatereviewstatus(candidateid),]).then((data) => { const candidateinfo = data[0][this.props.match.params.candidate_id]; const reviewinfo = data[1][0]; this.setstate({ /* sets various state parameters based on what was returned from the api calls*/ }); }).catch((err) => { this.props.handleerror(err); this.setstate({ error: err,}); });}

我在做什么是造成这种情况的原因error: method “setstate” is only meant to be run on a singlenode. 3 found instead.?

如果需要提供有关组件本身的更多信息,请告诉我。

在此先感谢您的帮助。

网友评论
评论
更多常见问答
  • 常见问答推荐
更多
最新软件下载
网站地图