1

In my application I have a global variable in an external file

const Translate = {
  trans: () => {... some code}
}

and I use it in my React component

const title = Translate.trans('title');

and in my Component.test.js

import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import Adapter from 'enzyme-adapter-react-16';
import Component from '../Component';
Enzyme.configure({ adapter: new Adapter() });

describe('Component Snapshot Tests', () => {
  it('renders default Component correctly', () => {
    const wrapper = shallow(<Component />);
    expect(toJson(wrapper)).toMatchSnapshot();
  });
});

afterEach(() => {
  global.Translator.trans = jest.fn(() => 'test text');
});

I get an error:

"TypeError: Translator.trans is not a function"

Jest settings

"jest": {
    "verbose": true,
    "rootDir": "./src",
    "globals": {
      "Translator": true
    }
  }

How better mock global variables in jest? Thanks!

Lin Du
  • 88,126
  • 95
  • 281
  • 483
VLlll
  • 51
  • 1
  • 1
  • 7

2 Answers2

0

Here is the solution, there is no need to set jest config.

index.ts:

import React from 'react';
import './Translate';

interface ISomeComponentProps {
  title: string;
}

class SomeComponent extends React.Component<ISomeComponentProps> {
  public render() {
    const title = (global as any).Translator.trans(this.props.title);
    return <div>title: {title}</div>;
  }
}

export { SomeComponent };

Translate.ts:

const Translator = {
  trans: text => text
};

(global as any).Translator = Translator;

export { Translator };

Unit test:

import React from 'react';
import { shallow } from 'enzyme';
import { SomeComponent } from './';

(global as any).Translator.trans = jest.fn();

describe('SomeComponent', () => {
  it('t1', () => {
    const mockTitle = 'test title';
    (global as any).Translator.trans.mockReturnValueOnce(mockTitle);
    const wrapper = shallow(<SomeComponent title={mockTitle} />);
    expect(wrapper.text()).toBe(`title: ${mockTitle}`);
    expect((global as any).Translator.trans).toBeCalledWith(mockTitle);
  });
});

Unit test result with coverage report:

 PASS  src/stackoverflow/47412169/index.spec.tsx
  SomeComponent
    ✓ t1 (14ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |    92.31 |      100 |    66.67 |    91.67 |                   |
 Translate.ts |       75 |      100 |        0 |       75 |                 2 |
 index.tsx    |      100 |      100 |      100 |      100 |                   |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.799s, estimated 6s

Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47412169

Lin Du
  • 88,126
  • 95
  • 281
  • 483
0

Here is one way that you can mock variables/function globally for Jest:

mockTranslate.js

// Globally mock gettext
global.gettext = jest.fn((text) => text);
global.pgettext = jest.fn((context, text) => text);

And then in your jest.config.js include it in the setupFiles:

const config = {
 // other configs
};


// HERE
config.setupFiles = ['./mockTranslate.js'];

module.exports = config;
nliu71
  • 86
  • 5