无法对覆盖 material-ui 的样式化组件进行单元测试
Can't unit test styled component that's overriding material-ui
我有一个用于导航列表项的样式组件,它包装了一个 Material-UI 列表项,并使用 '&&' 来覆盖样式而不使用 '!important ' 旗帜。
import { ListItem } from 'material-ui/List'
export const StyledNavListItem = withTheme()(styled(ListItem)`
&& {
background: ${props => props.selected
? props.theme.palette.backgrounds.selected
: 'inherit'};
}
`)
它是这样实现的:
export const NavListItem = props => {
return (
<StyledNavListItem selected={props.selected} component={Link} to={props.to || ''} onClick={props.onClick || (() => false)} button>
{props.icon && <ListItemIcon><Icon name={props.icon} /></ListItemIcon>}
<ListItemText primary={props.children || ''} />
</StyledNavListItem>
)
}
但是,当尝试在此处对其进行单元测试时(使用 Jest、enzyme 和 jest-styled-components):
it('should change the background color of an item if `props.selected` is truthy', () => {
const navList = mount(
<MuiThemeProvider theme={theme}>
<BrowserRouter>
<Route>
<NavList>
<NavListItem>item text</NavListItem>
<NavListItem selected>item text</NavListItem>
</NavList>
</Route>
</BrowserRouter>
</MuiThemeProvider>
)
expect(navList.find(StyledNavListItem).at(0)).toHaveStyleRule('background', '#e0e0e0')
expect(navList.find(StyledNavListItem).at(1)).toHaveStyleRule('background', theme.palette.backgrounds.selected)
})
我收到错误消息 Property not found: "background"
如果我从我的样式中删除“&&”包装器,测试将毫无问题地通过,但是我无法让样式在组件上工作。有什么方法可以进入覆盖块进行测试吗?
我找到了一个解决方案——通过在 material-ui 组件中指定自定义 类,然后在样式中引用它,它在附加修饰符的情况下测试正常
例子
Typography.style.js
import React from 'react'
import { withTheme } from 'material-ui/styles'
import styled, { css } from 'styled-components'
import Typography from 'material-ui/Typography'
export const StyledTypography = withTheme()(styled(({emphasized, strong, inlined, color, ...other}) => {
return <Typography {...other} classes={{root: 'typography-root'}} />
})`
&.typography-root {
line-height: 1.2em;
${props => !props.variant && css`
font-size: 1em;
`}
${props => props.color && props.theme.palette.typography[props.color] && css`
color: ${props.theme.palette.typography[props.color]};
`}
${props => props.strong && css`
font-weight: 500;
`}
${props => props.emphasized && css`
font-style: italic;
`}
${props => props.inlined && css`
display: inline-block;
`}
}
`)
测试
it('does something', () => {
const typography = mount(
<MuiThemeProvider theme={praxisTheme}>
<Typography />
</MuiThemeProvider>
)
expect(typography.find(MaterialUITypography)).toHaveStyleRule('line-height', '1.2em', { modifier: '&.typography-root' })
})
我有一个用于导航列表项的样式组件,它包装了一个 Material-UI 列表项,并使用 '&&' 来覆盖样式而不使用 '!important ' 旗帜。
import { ListItem } from 'material-ui/List'
export const StyledNavListItem = withTheme()(styled(ListItem)`
&& {
background: ${props => props.selected
? props.theme.palette.backgrounds.selected
: 'inherit'};
}
`)
它是这样实现的:
export const NavListItem = props => {
return (
<StyledNavListItem selected={props.selected} component={Link} to={props.to || ''} onClick={props.onClick || (() => false)} button>
{props.icon && <ListItemIcon><Icon name={props.icon} /></ListItemIcon>}
<ListItemText primary={props.children || ''} />
</StyledNavListItem>
)
}
但是,当尝试在此处对其进行单元测试时(使用 Jest、enzyme 和 jest-styled-components):
it('should change the background color of an item if `props.selected` is truthy', () => {
const navList = mount(
<MuiThemeProvider theme={theme}>
<BrowserRouter>
<Route>
<NavList>
<NavListItem>item text</NavListItem>
<NavListItem selected>item text</NavListItem>
</NavList>
</Route>
</BrowserRouter>
</MuiThemeProvider>
)
expect(navList.find(StyledNavListItem).at(0)).toHaveStyleRule('background', '#e0e0e0')
expect(navList.find(StyledNavListItem).at(1)).toHaveStyleRule('background', theme.palette.backgrounds.selected)
})
我收到错误消息 Property not found: "background"
如果我从我的样式中删除“&&”包装器,测试将毫无问题地通过,但是我无法让样式在组件上工作。有什么方法可以进入覆盖块进行测试吗?
我找到了一个解决方案——通过在 material-ui 组件中指定自定义 类,然后在样式中引用它,它在附加修饰符的情况下测试正常
例子 Typography.style.js
import React from 'react'
import { withTheme } from 'material-ui/styles'
import styled, { css } from 'styled-components'
import Typography from 'material-ui/Typography'
export const StyledTypography = withTheme()(styled(({emphasized, strong, inlined, color, ...other}) => {
return <Typography {...other} classes={{root: 'typography-root'}} />
})`
&.typography-root {
line-height: 1.2em;
${props => !props.variant && css`
font-size: 1em;
`}
${props => props.color && props.theme.palette.typography[props.color] && css`
color: ${props.theme.palette.typography[props.color]};
`}
${props => props.strong && css`
font-weight: 500;
`}
${props => props.emphasized && css`
font-style: italic;
`}
${props => props.inlined && css`
display: inline-block;
`}
}
`)
测试
it('does something', () => {
const typography = mount(
<MuiThemeProvider theme={praxisTheme}>
<Typography />
</MuiThemeProvider>
)
expect(typography.find(MaterialUITypography)).toHaveStyleRule('line-height', '1.2em', { modifier: '&.typography-root' })
})