j.doe
j.doe

Reputation: 1254

How do I mock this method chain in Jest?

zoomOut(callback) {
        // Zooms out the current screen
        this.view.current.zoomOut(300).done(() => {
            (hasCallback(callback)) && callback();
        });
    }

I'm trying to test the function above but I keep getting the following error:

TypeError: this.view.current.zoomOut(...).done is not a function

How can I mock this method chain in Jest?

Upvotes: 1

Views: 8407

Answers (2)

BudgieInWA
BudgieInWA

Reputation: 2255

You could try this:

const mockZoomOut = jest.fn(() => ({ done(cb) { cb(); } }));
const mockThis = {
    view: {
        current: {
            zoomOut: mockZoomOut,
        },
    },
};

test('it does', () => {
    const cb = jest.fn();
    zoomOut.apply(mockThis, [cb]);
    expect(mockZoomOut).toHaveBeenCalledTimes(1);
    expect(cb).toHaveBeenCalledTimes(1);
});

See Jest Mock Functions and fn.apply.

If you are testing the behaviour of the class as a whole, then you could set up the instance that you are testing to have this.view.current.zoomOut be mockZoomOut somehow.

Upvotes: 3

j.doe
j.doe

Reputation: 1254

Thanks to BudgieInWA, I was able to solve this problem by returning done.

For those who are testing a React component with Enzyme, here's how you can do it:

it('should call callback', () => {
    const wrapper = shallow(<Zoom {...minProps}/>);
    const instance = wrapper.instance();

    const callback = jest.fn();

    instance.view = {
        current: {
            zoomOut: jest.fn(() => {
                return {
                    done: jest.fn((callback) => {
                        callback();
                    })
                };
            })
        }
    };

    expect(callback).toHaveBeenCalledTimes(0);
    instance.zoomOut(callback);
    expect(callback).toHaveBeenCalledTimes(1);
});

Upvotes: 3

Related Questions