Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest+Enzyme. Cannot read property '_isMockFunction' of undefined. Simulate keyDown of Arrow

I have a serious problem with testing methods of my main component. My actual test after many retries still don't work and looks like this:

describe('<App />:', () => {
    beforeEach(() => {
        wrapper = mount(<Provider store={store}><App /></Provider>);
    });
    describe('Interaction:', () => {
        it('should call ArrowDown()', () => {
            const instance = wrapper.instance();
            spy = jest.spyOn(instance, 'ArrowDown');
            instance.forceUpdate();
            wrapper.simulate('keyDown', {key: 'Arrow down'});
            expect(spy).toHaveBeenCalled();
        });
    }); 
});

What I get from the console is:

TypeError: Cannot read property '_isMockFunction' of undefined

Other tests like snapshoting or finding other components inside of App works fine. I was searching for simillar problems but solutions I have found do not work as you can see. Please for help.

PS: Same error when I use prototype:

describe('<App />:', () => {
    beforeEach(() => {
        wrapper = mount(<Provider store={store}><App /></Provider>);
    });
    describe('Interaction:', () => {
            it('should call ArrowDown()', () => {
            spy = jest.spyOn(App.prototype, 'ArrowDown');
            wrapper = mount(<Provider store={store}><App /></Provider>);
            wrapper.simulate('keyDown', {key: 'Arrow down'});
            expect(spy).toHaveBeenCalled();
        });
    }); 
});
like image 840
Artimal Avatar asked Nov 28 '17 12:11

Artimal


1 Answers

It looks like jest.SpyOn(App.prototype, 'ArrowDown') is the line causing your issue. I'm not exactly sure why without looking at your App declaration but I would point out that this isn't how I would go about testing, and I'd venture that maybe this isn't the way that Jest/Enzyme is intended to be used.

In this test you're not actually testing anything other than the fact that React has successfully bound a keypress to a component function, which doesn't really exercise anything meaningful about your code, or any particular logic. I would normally write a test that simulates a button click and then inspects the new DOM state to check that the button click had the desired effect.

If there was a service call involved, I'd probably spy on the service layer, check that it was being called correctly and return a controlled value, then make sure that the DOM was in the correct state. Spying on individual component methods isn't really necessary when you do things this way.

like image 168
Duncan Thacker Avatar answered Nov 13 '22 01:11

Duncan Thacker