![](/img/trans.png)
[英]How to simulate an event on a unit test with Jest, Enzyme for React-Native
[英]How to access the variable of a component constructor within unit tests with React-Native and Jest / Enzyme?
现在,我一直在努力尝试访问组件构造函数内部的变量,以测试使用它的不同方法。 请参见下面的示例。
我的组件Timer的构造函数。 我想在我的timer.test.js文件中访问countDown 。
constructor(props){
super(props)
countDown = null,
...
}
以下是我要测试的功能之一(在其中使用了coutDown ):
pauseTimer(){
this.setState({timerIsActive : false})
clearInterval(countDown)
}
以下是我的timer.test.js文件的示例:
import React from 'react'
import renderer from 'react-test-renderer'
import {shallow} from 'enzyme'
const wrapper = shallow(<Timer/>)
const componentInstance = wrapper.instance()
describe('My timer ', () => {
it('Shallow rendering', () => {
expect(wrapper).toMatchSnapshot()
})
it('Should update state customeTimeValue to 20', ()=>{
componentInstance.setState({...componentInstance.state, customTimeValue : {focus : '20'}})
expect(componentInstance.state.customTimeValue.focus).toEqual('20')
})
it('isValueOutOfRange with 20 should return 20', ()=>{
componentInstance.setState({...componentInstance.state, customTimeValue : {focus : '20'}})
expect(componentInstance.isValueOutOfRange('focus')).toEqual(20)
})
it('isValueOutOfRange with 67 should return 59', ()=>{
componentInstance.setState({...componentInstance.state, customTimeValue : {focus : '67'}})
expect(componentInstance.isValueOutOfRange('focus')).toEqual(59)
我已经搜索了多个帖子和文档,但是这些都不是我想要的。 我自己尝试了其他方法,但没有结果。
我希望你们能够帮助我。 谢谢 !
根据您的代码, <Timer>
将全局countDown
和硬编码配置用于作业/娱乐间隔。
因此,我希望您使用jest.useFakeTimers()
来测试此组件。 就像是
const wrapper = shallow(<Timer />);
expect(getTime(wrapper)).toEqual('00:00');
expect(modeIsWork(wrapper)).toBeTruthy();
jest.advanceTimersByTime(jobInterval - 1);
expect(getTime(wrapper)).toEqual('04:59');
// should still be in "Work" mode
expect(modeIsWork(wrapper)).toBeTruthy();
jest.advanceTimersByTime(2);
// should get into "Rest" mode
expect(modeIsWork(wrapper)).toBeFalsy();
expect(getTime(wrapper)).toEqual('00:00');
其中的getTime
和modeIsWork
是假设的辅助函数,可使用wrapper.find()
和其他酶的方法检查/返回某些函数。 不能访问state
只能检查元素的类,属性和内部文本。
回到countDown
,当前是全局的(不确定是否是有意的)。 如果是全球性的,我们需要确保
const timer1 = shallow(<Timer />);
const timer2 = shallow(<Timer />);
clickPause(timer1);
jest.advanceTimersByTime(1001);
expect(getTime(timer2)).toEqual('00:00'); // second timer is also paused
但是我怀疑它有时是全局的,实际上您需要进行相反的测试:暂停一个计时器不会停止另一个计时器。
PS在共享计时器之间,我还看到decrementTimer
依赖于setInterval
但没有检查实际时间是否脆弱。 尽管定时器偏移在现代浏览器中似乎是固定的,但仍不能保证定时器将在1000ms之后精确调用。 而且由于您每次都无条件递减内部计数器,这意味着您肯定会越来越晚。 为了使解决方案更可靠,您还需要检查当前的日期时间并进行模拟,可能需要lolex
类的lolex
来模拟setInterval
和global.Date
,而global.Date
太多的人工工作。
感谢您的详细回答。 我设法找到一些东西来测试我的setInterval是否正常工作(见下文),但现在看来我无法重置假计时器。 我搜索了文档和帖子,但提供的解决方案对我不起作用。
it('decrementTimer in "focus state" after 1 second should return 4:59', ()=>
{
jest.useFakeTimers();
componentInstance.setState({...componentInstance.state, timerState :
'focus'})
expect(componentInstance.state.timer.focus.minutes).toEqual(5);
expect(componentInstance.state.timer.focus.seconds).toEqual(0);
componentInstance.decrementTimer();
jest.advanceTimersByTime(1000);
expect(componentInstance.state.timer.focus.minutes).toEqual(4);
expect(componentInstance.state.timer.focus.seconds).toEqual(59);
jest.useRealTimers();
})
it('decrementTimer in "focus state" after 1 second should return 4:59', ()=>
{
jest.useFakeTimers();
componentInstance.setState({...componentInstance.state, timer : {
focus : {
minutes : 5,
seconds : 0
}
},
timerState :'focus'})
expect(componentInstance.state.timer.focus.minutes).toEqual(5);
expect(componentInstance.state.timer.focus.seconds).toEqual(0);
componentInstance.decrementTimer();
jest.advanceTimersByTime(1000);
expect(componentInstance.state.timer.focus.minutes).toEqual(4);
expect(componentInstance.state.timer.focus.seconds).toEqual(59);
jest.useRealTimers();
})
因此,这里我们有两次相同的测试(出于测试目的)。 第一个测试工作,但第二个不因为setInterval的被调用后,它实际上是由2secs(如advanceTimersByTime提到的,而不是由一个)请参见下面递减:
expect(received).toEqual(expected) // deep equality
Expected: 59
Received: 58
158 | jest.advanceTimersByTime(1000);
159 | expect(componentInstance.state.timer.focus.minutes).toEqual(4);
> 160 | expect(componentInstance.state.timer.focus.seconds).toEqual(59);
| ^
161 | jest.useRealTimers();
162 | })
163 |
at Object.toEqual (timer.test.js:160:65)
因此,我想有两个计时器同时运行。 进行这项工作可以解决我最初的问题。 谢谢 !
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.