Jest Enzyme - 来自第三方库的回调函数的代码覆盖率

Jest Enzyme - Code Coverage for a callback function from third party Library

我有一个 React 应用程序,我正在使用 Jest 和 Enzyme 对该应用程序进行单元测试。我正在使用 returns 回调函数的第三方库。我正在努力完成回调函数内代码的代码覆盖。我尝试了 mocking 和 spyOn,但无法将其用于我的用例。我可以得到任何关于如何处理这个问题的建议吗?

我创建了示例代码以供参考

https://codesandbox.io/s/xenodochial-kilby-obnmt

someLibrary.js

export function getUserContext(callback) {
  var context = {
    userName: "TestUser",
    locale: "en-us"
  };
  callback(context);
}

MyApp.js


componentDidMount() {
    someLib.getUserContext((context) => {
      //want to cover these below lines
      //and some other codes inside this callback function
      this.setState({
        userName: context.userName,
        locale: context.locale
      });
      //some other code to cover
    });
  }

App.test.js - 截至目前

describe("App Component", () => {
  const wrapper = shallow(<App />);
  //const layout = wrapper.instance();
  it("renders the component", () => {
    expect(wrapper.exists()).toBe(true);
  });
  it("sets the user context", () => {
    //not sure what to write here inorder to cover
  });
});

jest.spyOn(object, methodName)覆盖原来的someLib.getUserContext()方法,可以用jest.spyOn(object, methodName).mockImplementation(() => customImplementation).

这样就可以得到customImplementation函数中的回调函数。 使用模拟数据调用此回调函数。

例如

MyApp.jsx:

import React, { Component } from 'react';
import * as someLib from './someLibrary';

export default class MyApp extends Component {
  constructor() {
    super();
    this.state = {
      userName: '',
      locale: '',
    };
  }
  componentDidMount() {
    someLib.getUserContext((context) => {
      this.setState({
        userName: context.userName,
        locale: context.locale,
      });
    });
  }

  render() {
    const { userName } = this.state;
    return <div>{userName}</div>;
  }
}

MyApp.test.jsx:

import React from 'react';
import { shallow } from 'enzyme';
import App from './MyApp';
import * as someLib from './someLibrary';

describe('App Component', () => {
  it('renders the component', () => {
    const wrapper = shallow(<App />);
    expect(wrapper.exists()).toBe(true);
  });

  it('sets the user context', () => {
    const getUserContextSpy = jest.spyOn(someLib, 'getUserContext').mockImplementation((callback) => {
      callback({ userName: 'mocked user name', locale: 'zh_CN' });
    });
    const wrapper = shallow(<App />);
    expect(wrapper.text()).toEqual('mocked user name');
    expect(getUserContextSpy).toBeCalledWith(expect.any(Function));
  });
});

测试结果:

 PASS  examples/68102090/MyApp.test.jsx (12.251 s)
  App Component
    ✓ renders the component (6 ms)
    ✓ sets the user context (2 ms)

----------------|---------|----------|---------|---------|-------------------
File            | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------|---------|----------|---------|---------|-------------------
All files       |     100 |      100 |     100 |     100 |                   
 MyApp.jsx      |     100 |      100 |     100 |     100 |                   
 someLibrary.js |     100 |      100 |     100 |     100 |                   
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        14.305 s