Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 418
Jerome Reinländer Avatar asked Nov 20 '25 02:11

Jerome Reinländer


2 Answers

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.

like image 140
Jerome Reinländer Avatar answered Nov 21 '25 14:11

Jerome Reinländer


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

like image 20
Dima Vishnyakov Avatar answered Nov 21 '25 15:11

Dima Vishnyakov