#reactjs #typescript #unit-testing #jestjs #react-functional-component
Вопрос:
есть ли в любом случае возможность модульного тестирования функции в функциональном компоненте react. Поскольку wrapper.instance()
для функциональных компонентов будет возвращено значение null, каков наилучший способ включить эту функцию в тест, чтобы получить максимальный охват.
const SimpleFC: React.FC = () => {
const callbackFunction = () => {
// Do Stuffs
}
return (
<ChildComponent callback={callbackFunction} />
)
}
export { SimpleFC };
В этом сегменте кода как мы можем вызвать callbackFunction
?
Заранее спасибо
Комментарии:
1. Тесты IMHO не должны быть сосредоточены на деталях реализации . Утверждение о том, вызывается ли функция, не добавляет никакого значения . Вместо этого вам следует проверить, как изменяется пользовательский интерфейс при вызове этой функции xyz. Делает ли что-то добавленное в пользовательский интерфейс или удаленное из пользовательского интерфейса . Ваш тест должен быть больше сосредоточен на том, как пользователь будет использовать ваше приложение . Пользователю все равно, вызывается ли ваша функция обратного вызова . Все, что его волнует, — это то, что он видит в пользовательском интерфейсе .
2. Каково поведение , которое реализует обратный вызов? Как ChildComponent собирается запустить его?
3. @Shyam да, что заботит пользователя, так это изменение пользовательского интерфейса, но для изменения пользовательского интерфейса нам нужно запустить функцию. Мой вопрос в том, как вызвать функцию, не взаимодействуя с дочерним компонентом.
Ответ №1:
Поскольку вы используете wrapper.instance()
API, я произвольно думаю, что вы используете enzyme
библиотеку. Вы можете использовать .invoke(invokePropName)(…args) => Любой> метод для ChildComponent
прямого вызова функции.
Напр.
SimpleFC.tsx
:
import React from 'react';
import ChildComponent from './ChildComponent';
const SimpleFC: React.FC = () => {
const callbackFunction = () => {
// Do Stuffs
console.log('Do Stuffs');
};
return <ChildComponent callback={callbackFunction} />;
};
export { SimpleFC };
ChildComponent.tsx
:
import React from 'react';
export default function ChildComponent({ callback }) {
return <div onClick={callback}>child component</div>;
}
SimpleFC.test.tsx
:
import { shallow } from 'enzyme';
import React from 'react';
import { SimpleFC } from './SimpleFC';
describe('67774847', () => {
it('should pass', () => {
const logSpy = jest.spyOn(console, 'log');
const wrapper = shallow(<SimpleFC />);
wrapper.invoke('callback')();
expect(logSpy).toBeCalledWith('Do Stuffs');
logSpy.mockRestore();
});
});
результат теста:
PASS examples/67774847/SimpleFC.test.tsx (8.752 s)
67774847
✓ should pass (48 ms)
console.log
Do Stuffs
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 | 90 | 100 | 66.67 | 90 |
ChildComponent.tsx | 66.67 | 100 | 0 | 66.67 | 4
SimpleFC.tsx | 100 | 100 | 100 | 100 |
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 9.654 s
Комментарии:
1. Я попробовал
invoke
сделать вот такwrapper.invoke('getCustomerAddress')()
, я получаю сообщение об ошибке «Это выражение невозможно вызвать. Тип «никогда» не имеет сигнатур вызовов.Аргумент ts(2349) типа «строка» не может быть присвоен параметру типа «никогда».»2. @sinthu225 Это проблема с типом TS, вы можете ввести
any
ее . Судя по вашему вопросу, я не могу воспроизвести эту проблему. ВgetCustomerAddress
вашем вопросе нет опоры для функций.3. Я отключил подкладку и наложил гипс как любой другой. Ошибка типа: ShallowWrapper::invoke() требует имени реквизита, значением которого является функция
4.
const wrapper = shallow(<Foo />); wrapper.find('button').invoke('onClick')().then(() => { // expect() });
Это сработает, если у нас будет кнопка или что-нибудь в этом роде