单元测试 React 功能组件的功能
Posted
技术标签:
【中文标题】单元测试 React 功能组件的功能【英文标题】:Unit test React functional component's function 【发布时间】:2021-08-18 19:48:48 【问题描述】:无论如何我们可以在反应功能组件中对功能进行单元测试。由于wrapper.instance()
将为功能组件返回 null,因此在测试中包含此功能以获得最大覆盖率的最佳方法是什么。
const SimpleFC: React.FC = () =>
const callbackFunction = () =>
// Do Stuffs
return (
<ChildComponent callback=callbackFunction />
)
export SimpleFC ;
在这段代码中我们如何调用callbackFunction
?
提前致谢
【问题讨论】:
恕我直言,测试不应专注于实现细节。断言一个函数是否被调用不会增加任何值。相反,您应该做的是测试调用 xyz 函数时 UI 的变化情况。是否将某些内容添加到 UI 或从 UI 中删除。您的测试应该更多地关注用户将如何使用您的应用程序。用户不关心你的 callbackFunction 是否被调用。他只关心他在 UI 中看到的内容。 回调实现的行为是什么? ChildComponent 将如何触发它? @Shyam 是的,用户关心的是 UI 更改,但要更改 UI,我们需要触发该功能。我的问题是如何在不与子组件交互的情况下调用函数。 【参考方案1】:通过您使用wrapper.instance()
API,我武断地认为您使用的是enzyme
库。您可以使用.invoke(invokePropName)(...args) => Any 方法直接调用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
【讨论】:
我试过invoke
这样wrapper.invoke('getCustomerAddress')()
我收到一个错误“这个表达式不可调用。类型'never'没有调用签名.ts(2349)类型'string'的参数不能分配给“从不”类型的参数。”
@sinthu225 是 TS 类型问题,你可以 typecast 到any
。根据您的问题,我无法重现此问题。您的问题中没有 getCustomerAddress
函数属性。
我禁用了 linting 并像 any 一样强制转换。 TypeError: ShallowWrapper::invoke() 需要一个 prop 的名称,其值为一个函数
const wrapper = shallow(<Foo />); wrapper.find('button').invoke('onClick')().then(() => // expect() );
如果我们有按钮或任何东西,这将起作用以上是关于单元测试 React 功能组件的功能的主要内容,如果未能解决你的问题,请参考以下文章
使用 react-navigation 中的 useRoute 进行 Jest 单元测试