我正在编写一个React应用,其中App.js里面有很多逻辑,将其余组件捆绑在一起并保持一致状态。我已经将一些App.js中的原始代码移至helpermodule.js并绑定了导入的函数,以便它们可以操纵App组件的状态。
这是我的设置:
App.js
import helperFunction from './helpermodule'
class App extends Component {
constructor(props) {
super(props)
this.state = { foo: 'bar' }
this.helperFunction = helperFunction.bind(this)
}
}
helpermodule.js
function helperFunction() {
this.setState({
bar: 'calculated' + this.state.foo,
})
}
export { helperFunction }
我想为helpermodule中的函数编写一个单元测试。在涉及此内容的酶或Jest文档中找不到相关的部分。目的是查看helperFunction对App状态有什么影响。
我已经尝试过类似的事情
test('helperFunction', () => {
let state = { foo: 'bar' }
let setState = (obj) => { this.state = obj }
return expect(helperFunction().bind(this))
.toBe({
...newShift,
id: 0,
})
}
但这只会返回一个错误; TypeError: Cannot read property 'state' of undefined
。也许我的整个方法是错误的,所以可以解决该问题,但我不确定。
答案 0 :(得分:0)
helpermodule.js
function helperFunction(stateFoo) {
return {bar: 'calculated' + stateFoo};
}
export { helperFunction }
然后使用结果在组件中设置状态。也不要在构造函数中使用setState。
import helperFunction from './helpermodule'
class App extends Component {
constructor(props) {
super(props)
this.state = { foo: 'bar', ...helperFunction('bar') }
}
}
这将使测试更容易,并且总体上来说是更好的结构。
答案 1 :(得分:0)
不知道您为什么要采用这种方法,但是这种奇怪且难以遵循和维护的方法,只是出于您的观点。问题是您正在将this
传递给绑定,而this
没有state
或setState
的属性,因此您应该传递模拟的this
。 / p>
这是怎么回事
describe('helperFunction', () => {
function helperFunction() {
// @ts-ignore
this.setState({
// @ts-ignore
bar: 'calculated' + this.state.foo,
})
}
it('updates the provided stateHolder', () => {
const stateHolder = {
state: { foo: 'bar' },
// don't use arrow function otherwise it won't react the state via this
setState(obj: any) {
this.state = obj;
},
};
const importedHelperFunction = helperFunction.bind(stateHolder);
importedHelperFunction();
expect(stateHolder.state.foo).toBe('calculatedbar');
});
});