最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Unit Test: How to mock document.getElementById() in react? - Stack Overflow

programmeradmin5浏览0评论

I want to test following code with jest.

Does anynoe know how to mock document.getElementById()?

if (document.getElementById('estateList')) {
    render(
        <Provider store={store}>
            <EstateList />
        </Provider>,
        window.document.getElementById('estateList')
    );
}


if (document.getElementById('articleList')) {
    render(
        <Provider store={store}>
            <ArticleList />
        </Provider>,
        window.document.getElementById('articleList')
    );
}

if (document.getElementById('articleDetail')) {
    render(
        <Provider store={store}>
            <ArticleDetail />
        </Provider>,
        window.document.getElementById('articleDetail')
    );
}

I think I can put render inside a function, like:

function estateList() {
    render(
        <Provider store={store}>
            <EstateList />
        </Provider>,
        window.document.getElementById('estateList')

    );
}

Then simply test estateList(), without mocking document.getElementById(), but is there anyway to mock document.getElementById()?

I want to test following code with jest.

Does anynoe know how to mock document.getElementById()?

if (document.getElementById('estateList')) {
    render(
        <Provider store={store}>
            <EstateList />
        </Provider>,
        window.document.getElementById('estateList')
    );
}


if (document.getElementById('articleList')) {
    render(
        <Provider store={store}>
            <ArticleList />
        </Provider>,
        window.document.getElementById('articleList')
    );
}

if (document.getElementById('articleDetail')) {
    render(
        <Provider store={store}>
            <ArticleDetail />
        </Provider>,
        window.document.getElementById('articleDetail')
    );
}

I think I can put render inside a function, like:

function estateList() {
    render(
        <Provider store={store}>
            <EstateList />
        </Provider>,
        window.document.getElementById('estateList')

    );
}

Then simply test estateList(), without mocking document.getElementById(), but is there anyway to mock document.getElementById()?

Share Improve this question edited Sep 6, 2020 at 9:03 Lin Du 103k135 gold badges334 silver badges565 bronze badges asked Mar 7, 2018 at 7:34 jimmyjimmy 1,7197 gold badges23 silver badges40 bronze badges 2
  • Instead of using document.getElementById(), you can try (if possible) using a ref. IE, <EstateList ref={(element) => {this.element = element;}} />, and then you can replace occurences of document.getElementById() with this.element instead, and your tests should run fine too. – sme Commented Mar 7, 2018 at 8:05
  • Take a look at github./airbnb/enzyme . It makes it very easy to create wrappers and explore them. – Vinicius Santana Commented Mar 7, 2018 at 8:54
Add a ment  | 

1 Answer 1

Reset to default 4

Using jest.fn(implementation) create mocked getElementById method and replace the method on document.

E.g.

index.tsx:

import React from 'react';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
import { createStore } from 'redux';

export const store = createStore(() => 0);

export const EstateList = () => <div>EstateList</div>;
export const ArticleList = () => <div>ArticleList</div>;
export const ArticleDetail = () => <div>ArticleDetail</div>;

function bootstrap() {
  if (document.getElementById('estateList')) {
    render(
      <Provider store={store}>
        <EstateList />
      </Provider>,
      window.document.getElementById('estateList'),
    );
  }

  if (document.getElementById('articleList')) {
    render(
      <Provider store={store}>
        <ArticleList />
      </Provider>,
      window.document.getElementById('articleList'),
    );
  }

  if (document.getElementById('articleDetail')) {
    render(
      <Provider store={store}>
        <ArticleDetail />
      </Provider>,
      window.document.getElementById('articleDetail'),
    );
  }
}

export { bootstrap };

index.test.tsx:

import React from 'react';
import { render } from 'react-dom';
import { bootstrap, store, EstateList, ArticleList, ArticleDetail } from './';
import { Provider } from 'react-redux';

jest.mock('react-dom');
const mockedRender = render as jest.Mocked<typeof render>;

describe('49146453', () => {
  let oGetElementById;
  beforeAll(() => {
    oGetElementById = document.getElementById;
  });
  afterAll(() => {
    document.getElementById = oGetElementById;
  });
  it('should render estatelist', () => {
    document.getElementById = jest.fn().mockImplementation((id) => (id === 'estateList' ? 'estateList-dom' : null));
    bootstrap();
    expect(mockedRender).toBeCalledWith(
      <Provider store={store}>
        <EstateList />
      </Provider>,
      'estateList-dom',
    );
  });

  it('should render articleList', () => {
    document.getElementById = jest.fn().mockImplementation((id) => (id === 'articleList' ? 'articleList-dom' : null));
    bootstrap();
    expect(mockedRender).toBeCalledWith(
      <Provider store={store}>
        <ArticleList />
      </Provider>,
      'articleList-dom',
    );
  });

  it('should render articleDetail', () => {
    document.getElementById = jest.fn().mockImplementation((id) => (id === 'articleDetail' ? 'articleDetail-dom' : null));
    bootstrap();
    expect(mockedRender).toBeCalledWith(
      <Provider store={store}>
        <ArticleDetail />
      </Provider>,
      'articleDetail-dom',
    );
  });
});

unit test result with coverage report:

 PASS  src/stackoverflow/49146453/index.test.tsx
  49146453
    ✓ should render estatelist (6ms)
    ✓ should render articleList (1ms)
    ✓ should render articleDetail (1ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    84.21 |      100 |       40 |      100 |                   |
 index.tsx |    84.21 |      100 |       40 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        5.618s, estimated 11s

The version about jest.js and related packages, check source code: https://github./mrdulin/jest-codelab/tree/master/src/stackoverflow/49146453

发布评论

评论列表(0)

  1. 暂无评论