Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple React-dnd jest tests "Cannot have two HTML5 backends at the same time"

Tags:

react-dnd

I have a jest test file with a number of tests in it.

import React from 'react';
import configureStore from 'redux-mock-store';
import {Provider} from "react-redux";
import renderer from "react-test-renderer";
import HTML5Backend from "react-dnd-html5-backend";
import {DragDropContextProvider} from "react-dnd";

describe('My Component Tests', () => {
    let mockStore;
    let store;

    beforeEach(() => {
        mockStore = configureStore();
        store = mockStore(mockData);
    });

    test(' test1', () => {
        const cmpt = <Provider store={store}>
            <DragDropContextProvider backend={HTML5Backend}>
                <MyComponent state={1}/>
            </DragDropContextProvider>
        </Provider>;

        const tree = renderer.create(cmpt).toJSON();
        expect(tree).toMatchSnapshot();
    });

    test(' test2', () => {
        const cmpt = <Provider store={store}>
            <DragDropContextProvider backend={HTML5Backend}>
                <MyComponent state={2}/>
            </DragDropContextProvider>
        </Provider>;

        const tree = renderer.create(cmpt).toJSON();
        expect(tree).toMatchSnapshot();
    });
});

The first test always work

But the subsequent ones always come up with this error :

 Error: Uncaught [Error: Cannot have two HTML5 backends at the same time.]

I am guessing this is because the HTMLBackend is treated as a singleton, and is used across tests which is not what I want. I want tests which run independantly.

Is there some was of creating an instance of the HTMLBackend in the beforeEach() function.

I have tried to encapsule the HTML5Backend into a singleton, but I get the same Problem :

let html5Backend = null;

function getSingleton() {
    if (!html5Backend) {
        html5Backend = HTML5Backend;
        debugger;
    }
    return html5Backend;
}
like image 227
Oliver Watkins Avatar asked Sep 24 '19 09:09

Oliver Watkins


1 Answers

I solved this by referencing HTMLBackend instance in the "describe" level, like so :

describe('My Component Tests', () => {
    let mockStore;
    let store;

    let htmlbe = HTML5Backend; //reference instance here!!!

    beforeEach(() => {
        mockStore = configureStore();
        store = mockStore(mockData);
    });

    test(' test1', () => {
        const cmpt = <Provider store={store}>
            <DragDropContextProvider backend={htmlbe }>
                <MyComponent state={1}/>
            </DragDropContextProvider>
        </Provider>;

        const tree = renderer.create(cmpt).toJSON();
        expect(tree).toMatchSnapshot();
    });

    test(' test2', () => {
        const cmpt = <Provider store={store}>
            <DragDropContextProvider backend={htmlbe }>
                <MyComponent state={2}/>
            </DragDropContextProvider>
        </Provider>;

        const tree = renderer.create(cmpt).toJSON();

This is the equivalent of having a singleton across all tests.

like image 82
Oliver Watkins Avatar answered Jan 04 '23 08:01

Oliver Watkins