问题描述
我想测试使用render prop渲染的jsx的内容。我使用 react-test-renderer 进行测试。
这是Menu
组件,具有我要测试的渲染道具:
<Menu
menuItems={createMenuItems(cities,onOpenCity)}
render={(openMenu,onClick,children) => (
<>
<Button
buttonRef={node => this.anchorEl = node}
onClick={onClick}
className={`${classes.iconWrapper} ${classes.marginIcons} ${openMenu && classes.active}`}
<Book fill={openMenu ? '#000' : '#fff'}/>
</Button>
{children(this.anchorEl)}
</>
)}
>
</Menu>
菜单组件如下:
class Menu extends React.Component {
static propTypes = {
menuItems: PropTypes.arrayOf(PropTypes.shape({text: PropTypes.string,defaultAction: PropTypes.object})).isRequired
};
state = {
openMenu: false,};
onToggleMenu() {
this.setState(prevState => ({openMenu: !prevState.openMenu}))
}
onCloseMenu() {
this.setState({openMenu: false})
}
render() {
const {openMenu} = this.state;
const {classes,render,menuItems} = this.props;
return render(
openMenu,() => this.onToggleMenu(),(anchorEl) => (<Popper open={openMenu} anchorEl={anchorEl} placement="bottom-end" transition
disablePortal>
{({TransitionProps,placement}) => (
<Grow
{...TransitionProps}
id="menu-list-grow"
style={{transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom'}}
>
<Paper>
<ClickAwayListener onClickAway={() => this.onCloseMenu()}>
<MenuList disablePadding>
{menuItems.map(menuItem => (
<MenuItem
key={menuItem.text}
className={classes.menuItem}
onClick={() => {
menuItem.action();
this.onCloseMenu();
}}>{menuItem.text}</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
))
}
}
我正在为此组件编写一些测试:
describe('Menu',() => {
const context = setupTeardownWithTestRenderer();
const menuItems = [
{
text: '1st item',action: () => {}
}
];
const renderFunction = (openMenu,children) => children(<Button onClick={onClick}>Menu</Button>);
function renderMenu() {
const WithRootMenu = withRoot(Menu);
const testRenderer = context.render(<WithRootMenu menuItems={menuItems} render={renderFunction}/>);
return testRenderer.root.findByType(Menu.Naked);
}
it('renders menu',() => {
const menu = renderMenu();
expect(menu.instance.state.openMenu).toBeFalsy();
const menuList = menu.findByType(MenuList);
console.log(menuList);
});
});
我想获取MenuList
,因为我想测试onClick
组件的MenuItem
道具上的功能。
我正在使用setupTeardownWithTestRenderer
函数设置测试:
export function setupTeardownWithTestRenderer() {
const context = new SimpleTestContext();
context.setupBeforeAfter();
return context;
}
SimpleTestContext是一个类,具有一些用于设置测试的帮助方法:
class SimpleTestContext {
defaultNodeMock = {
createNodeMock: (element) => {
if (element.type === 'input') {
// return document.createElement('input');
//console.log('createNodeMock got input',element.props);
}
if (element.type === 'textarea') {
// console.log('createNodeMock got textarea',element.props);
return document.createElement('textarea');
}
return null;
}
};
testRenderer = {unmount: () => {}}; // null object
setup() {
this.consoleErrorSpy = jest.spyOn(global.console,'error');
this.consoleErrorSpy.mockReset();
Document.prototype.exitFullscreen = jest.fn();
jest.useFakeTimers();
}
tearDown() {
this.testRenderer.unmount();
jest.runAllTimers();
jest.useRealTimers();
expect(this.consoleErrorSpy).not.toHaveBeenCalled();
}
act(func) {
TestRenderer.act(func);
}
render(jsx,options) {
this.testRenderer = TestRenderer.create(jsx,options);
return this.testRenderer;
}
renderWithDefaultNodeMock(jsx) {
return this.render(jsx,this.defaultNodeMock);
}
async waitForComponent(component) {
await waitForExpect(() => expect(
this.testRenderer.root.findAllByType(component)
.map(instance => ({ props: instance.props,type: instance.type }))).toHaveLength(1));
return this.testRenderer.root.findByType(component);
}
async waitForComponentByProps(props) {
await waitForExpect(() => expect(
this.testRenderer.root.findAllByProps(props)
.map(instance => ({props: instance.props,type: instance.type}))).toHaveLength(1));
return this.testRenderer.root.findByProps(props);
}
async waitForComponentToLoad(component) {
const instance = await this.waitForComponent(component);
await waitForExpect(() => expect(instance.instance.state.hasLoaded).toBeTruthy());
return instance;
}
setupBeforeAfter() {
beforeEach(() => {
this.setup();
});
afterEach(() => {
this.tearDown();
});
}
}
我的问题是,如果我运行测试以尝试找到MenuList,例如:
it('renders menu',() => {
const menu = renderMenu();
console.log(menu.instance);
const menuList = menu.findByType(MenuList);
console.log(menuList);
});
我得到一个错误:
错误:未找到节点类型为“ undefined”的实例
我如何测试使用render prop渲染jsx的组件渲染什么?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)