My test of a react component looks like this (based off this article):
// MyComponent.test.js
import { mount } from 'enzyme';
import MyComponent from './MyComponent.jsx';
describe('<MyComponent />', () => {
let props;
let state;
let mountedComponent;
// The problematic part to be changed
const component = () => {
if (!mountedComponent) {
// This enzyme mount is actually much more complex,
// as I'm wrapping all sorts of contexts and globals around it
// which is why I want to take this function outside,
// and use it as boilerplate in every test
mountedComponent = mount(<MyComponent {...props} />);
}
return mountedComponent;
};
beforeEach(() => {
props = {};
state = {};
mountedComponent = undefined;
});
it('Works', () => {
state = { val: true };
component().setState(state,
() => expect(component().state('val')).to.equal(true),
);
});
});
This works well, the component()
function properly returns the same mountedComponent
if called multiple times in the same it
, as the current value of mountedComponent is preserved between calls, and only resets beforeEach test.
Now if I extract the component()
function outside this test to another file:
// getMountedComponent.js
const getMountedComponent = (AnyComponent, props, mountedComponent) => {
if (!mountedComponent) {
// Appears not to properly reassign mountedComponent
mountedComponent = mount(<AnyComponent {...props} />);
}
return mountedComponent;
};
And replace the component()
function with this:
// MyComponent.test.js
// Cleaner problematic part
const component = () => getMountedComponent(MyComponent, props, mountedComponent);
Then this this test fails, because component() returns a fresh component the second time, with state = null.
It appears to be a scope issue, but I can't wrap my head around this?