0

我已经解决这个问题几天了,相信我已经接近解决方案了。我正在尝试模拟在我的useEffect

  useEffect(() => {
    getAdminOrg();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const getAdminOrg = () => {
    const token = localStorage.getItem("token");
    const URL = `organizations/organizations/`;
    let config = {
      headers: { Authorization: "JWT " + token }
    };
    axios
      .get(URL, config)
      .then(response => {
        setOrgTitle(response.data.name);
      })
      .catch(error => {
        if (error.response) {
          console.log(error.response);
          if (error.response.status === 401) {
            props.renewToken();
          }
        }
      });
  };

如果setOrgTitle钩子运行,我将能够通过更改文本字段来检测到这一点。我想在这里测试一下:

it("mocks API call", done => {
  const wrapper = mount(
    <OrganizationDocs />
  );
  const mock = new MockAdapter(axios);
  mock
    .onGet(`organizations/organizations/`, {
      headers: { Authorization: "JWT1111" }
    })
    .reply(200, response.data);

  setImmediate(() => {
    wrapper.update();
    expect(findByTestId(wrapper, "org-docs-header").text()).toContain(
      organizationsOrganizations[0].name
    );
    done();
  });
});

运行测试时,我收到未处理的承诺拒绝警告。此外,当我尝试控制台日志时,wrapper我可以看到 API 调用没有使用我正在应用的测试标头,所以我很确定 API 调用没有使用我的模拟。

任何帮助,将不胜感激。

4

1 回答 1

0

这是仅使用jestjs++的单元测试解决enzyme方案react-dom/test-utils

例如

index.ts

import React, { useEffect, useState } from 'react';
import axios from 'axios';

export const OrganizationDocs = (props) => {
  const [orgTitle, setOrgTitle] = useState('');

  useEffect(() => {
    getAdminOrg();
  }, []);

  const getAdminOrg = () => {
    const token = localStorage.getItem('token');
    const URL = `organizations/organizations/`;
    let config = {
      headers: { Authorization: 'JWT ' + token },
    };
    axios
      .get(URL, config)
      .then((response) => {
        setOrgTitle(response.data.name);
      })
      .catch((error) => {
        if (error.response) {
          console.log(error.response);
          if (error.response.status === 401) {
            props.renewToken();
          }
        }
      });
  };

  return <div className="org-docs-header">orgTitle: {orgTitle}</div>;
};

index.spec.ts

import React from 'react';
import { OrganizationDocs } from '.';
import { mount } from 'enzyme';
import axios from 'axios';
import { act } from 'react-dom/test-utils';

const mLocalStorage = {
  _storage: {},
  getItem: jest.fn((key) => {
    return mLocalStorage._storage[key];
  }),
  setItem: jest.fn((key, value) => {
    mLocalStorage._storage[key] = value;
  }),
};
Object.defineProperty(window, 'localStorage', {
  value: mLocalStorage,
});

describe('MyComponent', () => {
  afterEach(() => {
    jest.restoreAllMocks();
    jest.resetAllMocks();
  });
  it('mocks API call', async () => {
    const token = 'JWT1111';
    mLocalStorage.setItem('token', token);
    const response = { data: { name: 'mocked name' } };
    jest.spyOn(axios, 'get').mockResolvedValueOnce(response);
    const wrapper = mount(<OrganizationDocs />);
    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });
    expect(wrapper.find('.org-docs-header').text()).toContain('mocked name');
    expect(axios.get).toBeCalledWith('organizations/organizations/', {
      headers: { Authorization: 'JWT ' + token },
    });
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59379085/index.spec.tsx (9.958s)
  MyComponent
    ✓ mocks API call (85ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    78.95 |        0 |       80 |    76.47 |                   |
 index.tsx |    78.95 |        0 |       80 |    76.47 |       23,24,25,26 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.427s

源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59379085

于 2019-12-18T04:27:12.070 回答