像 'useLocation' 这样的反应路由器钩子的存根不起作用



我正在尝试为 React 功能组件编写单元测试,该功能组件具有如下所示useLocation()路由器钩子。

//index.js
function MyComponent(props) {
const useQuery = () => new URLSearchParams(useLocation().search);
const status = useQuery().get('status');
if (status === 'success') {
return <ShowStatus message="OK" secret={props.secret} />;
} else {
return <ShowStatus message="NOT OK" secret={props.secret} />;
}
}
//index.spec.js
describe('Test MyComponent', () => {
it('should send OK when success', () => {
sinon.stub(reactRouter, 'useLocation').returns({
search: {
status: 'success'
}
});
const props = { secret: 'SECRET_KEY' };
const wrapper = enzyme.shallow(<MyComponent.WrappedComponent {...props}/>);
expect(wrapper.type()).to.have.length(MyComponent);
expect(wrapper.props().message).to.equal('OK');
expect(wrapper.props().secret).to.equal(props.secret);
});
it('should send NOT OK when error', () => {
sinon.stub(reactRouter, 'useLocation').returns({
search: {
status: 'error'
}
});
const props = { secret: 'SECRET_KEY' };
const wrapper = enzyme.shallow(<MyComponent.WrappedComponent {...props}/>);
expect(wrapper.type()).to.have.length(MyComponent);
expect(wrapper.props().message).to.equal('NOT OK);
expect(wrapper.props().secret).to.equal(props.secret);
});
});

即使我在遇到错误useLocation也在存根

TypeError: Cannot read property 'location' of undefined
at useLocation (node_modulesreact-routermoduleshooks.js:28:10)

我正在尝试测试组件是否ShowStatus基于查询参数使用正确的道具进行渲染。

任何建议/帮助不胜感激。

更新:即使我在生产和测试代码中从react-router-dom导入,我也注意到。我看到产品一正在从react-router.

使用 MemoryRouter 组件包装您的组件比存根useLocation钩子更好。

将"URL"的历史记录保存在内存中(不读取或写入地址栏(。在测试和非浏览器环境(如 React Native(中很有用。

我们可以通过 initialEntries 属性提供被测试组件的"URL"。

index.tsx

import React from 'react';
import { useLocation } from 'react-router-dom';
export function ShowStatus({ message, secret }) {
return <div>{message}</div>;
}
export function MyComponent(props) {
const useQuery = () => new URLSearchParams(useLocation().search);
const status = useQuery().get('status');
if (status === 'success') {
return <ShowStatus message="OK" secret={props.secret} />;
} else {
return <ShowStatus message="NOT OK" secret={props.secret} />;
}
}

index.test.tsx

import { mount } from 'enzyme';
import React from 'react';
import { MemoryRouter } from 'react-router';
import { MyComponent, ShowStatus } from './';
describe('MyComponent', () => {
it('should send OK when success', () => {
const props = { secret: 'SECRET_KEY' };
const wrapper = mount(
<MemoryRouter initialEntries={[{ search: '?status=success' }]}>
<MyComponent {...props} />
</MemoryRouter>
);
expect(wrapper.find(ShowStatus).props().message).toEqual('OK');
expect(wrapper.find(MyComponent).props().secret).toEqual(props.secret);
});
it('should send NOT OK when error', () => {
const props = { secret: 'SECRET_KEY' };
const wrapper = mount(
<MemoryRouter initialEntries={[{ search: '?status=error' }]}>
<MyComponent {...props} />
</MemoryRouter>
);
expect(wrapper.find(ShowStatus).props().message).toEqual('NOT OK');
expect(wrapper.find(MyComponent).props().secret).toEqual(props.secret);
});
});

测试结果:

PASS  examples/59829930/index.test.tsx (8.239 s)
MyComponent
✓ should send OK when success (55 ms)
✓ should send NOT OK when error (8 ms)
-----------|---------|----------|---------|---------|-------------------
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:       2 passed, 2 total
Snapshots:   0 total
Time:        9.003 s

软件包版本:

"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-router-dom": "^5.2.0",

相关内容

  • 没有找到相关文章

最新更新