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
我有一个 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