#reactjs #unit-testing #jestjs #enzyme
Вопрос:
У меня есть приложение React, и я использую Jest и Enzyme для модульного тестирования приложения. Я использую стороннюю библиотеку, которая возвращает функцию обратного вызова. Я изо всех сил пытаюсь завершить покрытие кода для кода внутри функции обратного вызова. Я пробовал издеваться и шпионить, но не смог использовать это в своем случае. Могу ли я получить какие-либо предложения о том, как подойти к этому?
Я создал образец кода для справки
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
});
});
Ответ №1:
Используйте jest.spyOn(объект, имя метода), чтобы перезаписать исходный 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