How to fix this Jest error: "component encountered a declaration exception"?

20,926

The default test environment for Jest is a browser-like environment provided by jsdom, which supplies a simulated window which is also the global object.

You can call require on the third-party script to get its exports and set those on global (or window) at the beginning of the test (or do that in a setupFilesAfterEnv setup module if it is needed for every test):

global.TimerSDK = require('path-to-script');  // <= set the module exports on global
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
import App from './App';

Enzyme.configure({
  adapter: new EnzymeAdapter()
});

describe('App Component', () => {
  const app = shallow(<App />);

  it('renders successfully', () => {
    expect(app).toMatchSnapshot();
  });
});
Share:
20,926
Admin
Author by

Admin

Updated on March 21, 2020

Comments

  • Admin
    Admin about 4 years

    I'm trying to test a React component using Jest and Enzyme. My test is very simple at the moment, I'm just trying to make sure the component mounts:

    import React from 'react';
    import Enzyme, { shallow } from 'enzyme';
    import EnzymeAdapter from 'enzyme-adapter-react-16';
    import App from './App';
    
    Enzyme.configure({
      adapter: new EnzymeAdapter()
    });
    
    describe('App Component', () => {
      const app = shallow(<App />);
    
      it('renders successfully', () => {
        expect(app).toMatchSnapshot();
      });
    });
    

    Running it gives the following error:

    App Component › encountered a declaration exception
    TypeError: window.TimerSDK is not a constructor
    

    The offending line in question is this bit of code:

    this.timerSDK = new window.TimerSDK({ accessToken: token });
    

    TimerSDK is a third party script that is loaded via a script tag in index.html. It's not imported like an es6 module.

    The code above works fine in the browser when actually using the app but when running the test it errors out.

    How to fix this?

  • Admin
    Admin about 5 years
    The component isn't modifying the window object, it's just calling methods on the TimerSDK object. What you said about importing the script in the test makes sense but doing so doesn't get rid of the error unfortunately :(
  • Brian Adams
    Brian Adams about 5 years
    @TK123 what is the third party library? I'll take a look at how it works and update my answer
  • Admin
    Admin about 5 years
    Ah thanks for the help but it's an internal one so I can't post it, "TimerSDK" was a placeholder lie lol All I can say is it's written in requireJS module syntax, don't know much else about it it's all minified. Maybe that's the issue since I noticed that script can't be imported in a regular component without throwing errors (hence my reason for loading it as a script tag in the first place). So maybe importing it in the test is failing also...
  • Brian Adams
    Brian Adams about 5 years
    @TK123 gotcha, I've updated my answer for a script using requireJS module syntax