[英]How do I mock "this" when writing a unit test for a React module?
I'm writing a React app where the App.js has a lot of logic inside it tying together the rest of the components and keeping a coherent state.我正在编写一个 React 应用程序,其中 App.js 内部有很多逻辑将其余组件联系在一起并保持一致状态。 I have moved some of the code that were originally in App.js to helpermodule.js and bind the imported functions so that they can manipulate the state of the App component.
我已经将原本在 App.js 中的一些代码移到了 helpermodule.js 并绑定了导入的函数,以便它们可以操纵 App 组件的状态。
This is my setup:这是我的设置:
App.js应用程序.js
import helperFunction from './helpermodule'
class App extends Component {
constructor(props) {
super(props)
this.state = { foo: 'bar' }
this.helperFunction = helperFunction.bind(this)
}
}
helpermodule.js辅助模块.js
function helperFunction() {
this.setState({
bar: 'calculated' + this.state.foo,
})
}
export { helperFunction }
And I want to write a unit test for the function(s) inside the helpermodule.我想为 helpermodule 中的函数编写一个单元测试。 I can't find the relevant parts in the Enzyme or Jest documentation where this is covered.
我在 Enzyme 或 Jest 文档中找不到相关部分。 The goal is to see what effect helperFunction has on the App state.
目标是查看 helperFunction 对 App 状态有什么影响。
I have tried things like this我试过这样的事情
test('helperFunction', () => {
let state = { foo: 'bar' }
let setState = (obj) => { this.state = obj }
return expect(helperFunction().bind(this))
.toBe({
...newShift,
id: 0,
})
}
But that just returns an error;但这只会返回一个错误;
TypeError: Cannot read property 'state' of undefined
. TypeError: Cannot read property 'state' of undefined
。 Perhaps my entire approach is wrong so the problem can be circumvented but I'm not sure.也许我的整个方法都是错误的,所以可以规避这个问题,但我不确定。
helpermodule.js辅助模块.js
function helperFunction(stateFoo) {
return {bar: 'calculated' + stateFoo};
}
export { helperFunction }
Then use the result to set state in the component.然后使用结果在组件中设置状态。 Also don't setState in constructor.
也不要在构造函数中设置状态。
import helperFunction from './helpermodule'
class App extends Component {
constructor(props) {
super(props)
this.state = { foo: 'bar', ...helperFunction('bar') }
}
}
This will make testing easier as well as being a better structure in general.这将使测试更容易,并且总体上是一个更好的结构。
no idea why would you follow this approach it is so weird and hard to follow and maintain but for the sake of your argument.不知道你为什么要遵循这种方法,但为了你的论点,它是如此奇怪和难以遵循和维护。 the issue is that you are passing
this
to the bind while this
has no property of state
or setState
so you should pass a mocked this
instead.问题是您将
this
传递给绑定,而this
没有state
或setState
属性,因此您应该传递一个模拟的this
。
here is how it could go这是它的方式
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');
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.