#reactjs #unit-testing #jestjs #enzyme #react-context
Вопрос:
Я видел несколько примеров того, как имитировать контекст и как имитировать вызов конкретной функции компонента, но я не нашел ни одного, который выполнял бы и то, и другое одновременно. В большинстве случаев для правильного насмешливого контекста рекомендуется использовать mount()
, но тогда это не дает мне доступа к возвращаемому экземпляру, из shallow(<MyComponent>).instance()
которого я затем использовал бы вызов функции. Это пример ситуации, которую я пытаюсь проверить:
class MyComponent extends Component {
static contextType = MyContext
constructor(props) {
super(props);
this.myFunction = this.myFunction.bind(this);
}
myFunction() {
this.context.otherFunction('shouldBecorrectValue');
}
}
В идеале я хотел бы иметь возможность сделать это без изменения тестируемого кода.
Ответ №1:
Существует .instance() => ReactComponent> метод для оболочки, возвращаемой mount
. Работает только для компонента класса.
Возвращает экземпляр базового класса узла оболочки с одним узлом.
index.tsx
:
import React, { Component } from 'react';
const MyContext = React.createContext({
otherFunction: (value) => {
console.log(value);
},
});
export class MyComponent extends Component {
static contextType = MyContext;
myFunction() {
this.context.otherFunction('shouldBecorrectValue');
}
render() {
return <div>my component</div>;
}
}
index.test.tsx
:
import { mount } from 'enzyme';
import React from 'react';
import { MyComponent } from './';
describe('69127076', () => {
test('should pass', () => {
const logSpy = jest.spyOn(console, 'log');
const wrapper = mount(<MyComponent />);
wrapper.instance()['myFunction']();
expect(logSpy).toBeCalledWith('shouldBecorrectValue');
logSpy.mockRestore();
});
});
результат теста:
PASS examples/69127076/index.test.tsx (10.228 s)
69127076
✓ should pass (47 ms)
console.log
shouldBecorrectValue
at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.tsx | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.804 s
версии пакетов:
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"react": "^16.14.0",
"react-dom": "^16.14.0",
Комментарии:
1. Кроме того, ваш пример не показывает, как вы издеваетесь над контекстом в тесте. В настоящее время я занимаюсь этим:
context = {otherFunction: jest.fn()}
иmount(<MyComponent>, {context}).instance()
. Нужно ли мне также использоватьReact.createContext(context)
?2. Извините, я имел в виду, что могу создать экземпляр, но всякий раз, когда я это делаю, мне кажется, что это приводит
thrown: undefined
к ошибке при тестировании. Поэтому я предположил, что был какой-то другой шаг, который я пропустил.