3

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.

Community
  • 1
  • 1
Jerome Reinländer
  • 1,227
  • 1
  • 10
  • 26
  • Possible duplicate of [Jest es6 modules: unexpected module import](https://stackoverflow.com/questions/43366382/jest-es6-modules-unexpected-module-import) – Jerome Reinländer Jan 28 '19 at 10:11

2 Answers2

2

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 babel-core@6.26.3, 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.

Jerome Reinländer
  • 1,227
  • 1
  • 10
  • 26
  • 1
    You can try to use Create React App and eject it, if you need. They solved all this package trickery. Life is too short for manual configuration. https://github.com/facebook/create-react-app – Dima Vishnyakov Jan 28 '19 at 12:22
  • @DimaVishnyakov I have to admit I am not very familiar with the tools of the javascript world, so could you elaborate what you mean by "using and ejecting it"? – Jerome Reinländer Jan 29 '19 at 12:22
  • `npx create-react-app app-name` downloads and configures modern React application framwerok from Facebook. Create-react-app (CRA) has everything to start development (including Jest and eslint), and requires zero configuration. Just `yarn start` and code. Eventually you may need more precise control over your app config. To achieve that you can `yarn eject` which exposes internal configuration options. https://github.com/facebook/create-react-app – Dima Vishnyakov Jan 29 '19 at 14:25
1

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

Dima Vishnyakov
  • 1,361
  • 10
  • 21
  • 1
    Thanks for the hint, I appreciate it a lot! However I am not sure if this should be posted as an answer or a comment as it not answers the main question. Still a +1, because it is actually helpful. – Jerome Reinländer Jan 28 '19 at 11:09