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. 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.
This is my setup:
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 }
And I want to write a unit test for the function(s) inside the helpermodule. I can't find the relevant parts in the Enzyme or Jest documentation where this is covered. The goal is to see what effect helperFunction has on the App state.
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
. Perhaps my entire approach is wrong so the problem can be circumvented but I'm not sure.
helpermodule.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.
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');
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.