Jerome Reinländer
Jerome Reinländer

Reputation: 1257

Jest import of plain javascript results in unexpected token

Firstly: as far as I can tell, this is not a duplicate. The other questions with similar problems are all slightly different, e.g. use a transformation like babel or have problems with transitive imports. In my case I have no transformation, I have one test file and one file imported file that will be tested. I just started using jest and use the default setting, so there is no configuration file to post.

When I try to run my tests I get the error message:

Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

The tested file:

export function showTooltip(x, y, content) {
    const infoElement = document.getElementById('info');
    infoElement.style.left = `${x}px`;
    infoElement.style.top = `${y}px`;
    infoElement.style.display = 'block';
    infoElement.innerText = createTooltipText(content);
}

function createTooltipText(object) {
    return Object.keys(object)
        .filter(key => key != 'id')
        .map(key => `${key} : ${object[key]}`)
        .join('\n');
}

export function hideTooltip() {
    const infoElement = document.getElementById('info');
    infoElement.style.display = 'none';
}

The test:

import {showTooltip, hideTooltip} from '../../../src/public/javascripts/tooltip.js';

const TOOLTIP_DUMMY = {
    style: {
        left: 0,
        top: 0,
        display: '',
        innerText: ''
    }
};

test('showTooltip accesses the element with the id \'info\'', () => {
    const getElementByIdMock = jest.fn(() => TOOLTIP_DUMMY);
    document.getElementById = getElementByIdMock;
    showTooltip(0, 0, {});

    expect(getElementByIdMock).toHaveBeenCalledWith('info');
});

test('hideTooltip accesses the element with the id \'info\'', () => {
    const getElementByIdMock = jest.fn(() => TOOLTIP_DUMMY);
    document.getElementById = getElementByIdMock;
    hideTooltip();

    expect(getElementByIdMock).toHaveBeenCalledWith('info');
});

As you can see I am using plain javascript so I am not sure what to do here. The error message gives further hints about Babel which does not really apply to my case.

Sidenote: My test might be flawed. I am currently trying to figure out how to use mocks to avoid interaction with the document and I am not sure if that is the way. However this is not the point of this question as it should not affect the ability of the tests to run, but I am very open for suggestions.

EDIT: Why this is not a duplicate to this question: It kind of is, but I feel that question and the accepted answer were not really helpful for me and hopefully someone will profit from this one.

Upvotes: 3

Views: 2986

Answers (2)

Jerome Reinländer
Jerome Reinländer

Reputation: 1257

I have found the solution to my problem:

As suggested in this answer, you need to use Babel. This can be done as suggested here, but I used @babel/env-preset as it is suggested on the Babel website. This left me with the problem that jest internally uses [email protected], but at least babel 7 was required. This problem is described here. I used the temporary fix of manually copying and overwriting babel-core from my node-modules directory to the node-modules directories of jest-config and jest-runtime. This dirty fix is also described in the previous link.

I have yet to find a clean solution, but at least this works.

Upvotes: 2

Dima Vishnyakov
Dima Vishnyakov

Reputation: 1542

Use global.document.getElementById = getElementByIdMock; In some configurations Jest doesn't have access to document object directly.

Upvotes: 1

Related Questions