javascript - React 上下文测试 - 在 HOC 中模拟消费者
问题描述
我正在尝试测试我的组件,该组件通过 HOC 从上下文中消耗数据。
这是设置:模拟上下文模块/context/__mocks__
const context = { navOpen: false, toggleNav: jest.fn() }
export const AppContext = ({
Consumer(props) {
return props.children(context)
}
})
高阶组件/context/withAppContext
import React from 'react'
import { AppContext } from './AppContext.js'
/**
* HOC with Context Consumer
* @param {Component} Component
*/
const withAppContext = (Component) => (props) => (
<AppContext.Consumer>
{state => <Component {...props} {...state}/>}
</AppContext.Consumer>
)
export default withAppContext
零件NavToggle
import React from 'react'
import withAppContext from '../../../context/withAppContext'
import css from './navToggle/navToggle.scss'
const NavToggle = ({ toggleNav, navOpen }) => (
<div className={[css.navBtn, navOpen ? css.active : null].join(' ')} onClick={toggleNav}>
<span />
<span />
<span />
</div>
)
export default withAppContext(NavToggle)
最后是测试套件/navToggle/navToggle.test
import React from 'react'
import { mount } from 'enzyme'
beforeEach(() => {
jest.resetModules()
})
jest.mock('../../../../context/AppContext')
describe('<NavToggle/>', () => {
it('Matches snapshot with default context', () => {
const NavToggle = require('../NavToggle')
const component = mount( <NavToggle/> )
expect(component).toMatchSnapshot()
})
})
测试只是为了开始,但我面临这个错误:
Warning: Failed prop type: Component must be a valid element type!
in WrapperComponent
我认为这是 HOC 的问题,我应该以某种方式而不是 AppContext 模拟它,因为从技术上讲,AppContext 不是由 NavToggle 组件直接调用,而是在包装组件中调用。
提前感谢您的任何意见。
解决方案
所以我解决了。
我的上述尝试几乎没有问题。
- require 不理解默认导出,除非您指定它
- 安装空白组件返回错误
__mock__
当我想修改上下文进行测试时,用文件模拟 AppContext会导致问题
我已经按照以下方式解决了。我使用自定义上下文作为参数创建了模拟 AppContext 的辅助函数
export const defaultContext = { navOpen: false, toggleNav: jest.fn(), closeNav: jest.fn(), path: '/' }
const setMockAppContext = (context = defaultContext) => {
return jest.doMock('../context/AppContext', () => ({
AppContext: {
Consumer: (props) => props.children(context)
}
}))
}
export default setMockAppContext
然后测试文件结束看起来像这样
import React from 'react'
import { shallow } from 'enzyme'
import NavToggle from '../NavToggle'
import setMockAppContext, { defaultContext } from '../../../../testUtils/setMockAppContext'
beforeEach(() => {
jest.resetModules()
})
describe('<NavToggle/>', () => {
//...
it('Should have active class if context.navOpen is true', () => {
setMockAppContext({...defaultContext, navOpen: true})
const NavToggle = require('../NavToggle').default //here needed to specify default export
const component = shallow(<NavToggle/>)
expect(component.dive().dive().hasClass('active')).toBe(true) //while shallow, I needed to dive deeper in component because of wrapping HOC
})
//...
})
另一种方法是导出组件两次,一次是用 HOC 装饰的,一次是干净的组件并在其上创建测试,只是使用不同的道具测试行为。然后仅测试 HOC 作为单元,它实际上将正确的道具传递给任何包装的组件。
我想避免这种解决方案,因为我不想修改项目文件(即使它只是一个词)只是为了适应测试。
推荐阅读
- java - JavaFX LineChart NullPointer
- sql-server - 解决由于参数嗅探导致的间歇性性能问题
- python - 从恢复的张量流模型中获取“损失”函数
- java - Java Socket 无法使用 NoRouteToHostException 而不是 ConnectionRefused 连接到“0.0.0.0”
- php - 在php中使用ics文件删除日历邀请
- laravel - Laravel - 具有单个 Vue 实例的 Vue 多页面应用程序
- mongoose - 无法更新行 mongoose
- r - 在 R 中生成具有随机选择的特征的数据集列表
- android - 活动视图显示在片段上
- png - Ghostscript -- 将 PS 转换为 PNG、旋转和缩放