如何使用 Enzyme 测试 React 组件属性的样式
How to test style for a React component attribute with Enzyme
我正在尝试测试 React 组件的样式属性。在测试中获取样式参数的最佳方法是什么?
目前,我最好的选择是测试 HTML 是否包含字符串,但我认为还有更好的选择。
案例:
it('Should render large image when desktop', () => {
const dummyUrl = 'http://dummyUrl';
const wrapper = shallow(
<MockedStore
initialState={{
app: fromJS({ browser: { desktop: true } }),
}}
>
<LandingHero bigImage={dummyUrl} />
</MockedStore>
);
});
要测试的组件是:
// @flow
import React, { Component } from 'react';
import gc from 'styles/core.scss';
import $ from 'jquery';
import DownloadButton from 'components/DownloadButton';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import DownArrow from 'components/DownArrow';
import { connect } from 'react-redux';
import type { Map } from 'immutable';
import c from './styles.scss';
@withStyles([gc, c])
@connect(({ app }) => ({ app }))
class LandingHero extends Component {
componentDidMount() {
if ($(window).height() > 0) { // Necesary for webpack dev server
$(this.hero).css('height', $(window).height() - 46);
}
}
hero: HTMLElement;
props: {
app: Map<string, any>,
copy: string,
secondaryText: string,
thirdText: string,
bigImage?: string,
smallImage: string,
}
render() {
const { copy, secondaryText, thirdText } = this.props;
const browser = this.props.app.has('browser') ? this.props.app.get('browser') : {};
const backgroundImage = browser.desktop ? this.props.bigImage : this.props.smallImage;
return (
<div
className={`${c.hero} ${gc.textCenter}` +
` ${gc.alignMiddle} ${gc.alignCenter} ${gc.row} ${gc.expanded}`}
ref={(hero) => { this.hero = hero; }}
style={{
margin: 0,
position: 'relative',
background: `linear-gradient(to bottom, rgba($ixdarkprimary, .3), rgba($ixdarkprimary, .3)), url(${backgroundImage || ''})`,
}}
>
<div className={`${gc.row} ${gc.alignCenter} ${gc.alignMiddle} ${gc.column} ${gc.medium10}`}>
<div className={`${gc.textCenter}`}>
<div
className={`${gc.white} ${c.mainText} ${c.copy}`}
>
{ copy }
</div>
<div className={`${gc.small6} ${gc.smallOffset3} ${gc.medium4} ${gc.mediumOffset4}`} style={{ marginBottom: 45 }}>
<DownloadButton />
</div>
<div className={`${gc.white} ${gc.fontBold} ${gc.font24}`}>{secondaryText}</div>
<p className={`${gc.white} ${gc.font20}`}>{thirdText}</p>
</div>
<DownArrow goTo="#content" />
</div>
</div>
);
}
}
export default LandingHero;
看看 chaiEnzyme,它提供了一个方便的小断言,您可以将其与 chai 一起使用来检查包装器是否具有特定样式 (https://github.com/producthunt/chai-enzyme#stylekey-val),这应该有助于使您的测试看起来更清晰一些。
您可以使用this方法。它 returns ReactElement.
let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');
expect(component.find('#item-id').prop('style')).to.deep.equal({display: 'none'})
稍微阐述一下别人的答案:
expect(component.find('#item-id').prop('style')).toHaveProperty('backgroundSize', '100%');
这将检查 #item-id
的 style
属性。这个道具是一个对象,这里 toHaveProperty
匹配器检查这个对象是否包含 backgroundSize
属性 以及它的值是否为 100%
。
这样其他样式属性将被忽略。
如果你使用 jest-styled-components 那么你可以使用 toHaveStyleRule
如下:
expect(component.find('#item-id')).toHaveStyleRule('opacity', 'red');
const elem = wrapper.find(Element);
expect(getComputedStyle(elem.getDOMNode()).getPropertyValue('opacity')).toBe('0.4');
补充一下,下面的props()
方法也可以。
https://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html
let containerStyleOpacity = container.get(0).props().style.opacity;
expect(containerStyleOpacity).to.be.equal('1');
对我来说,这是几个答案的混搭。
对于那些也使用 Jest / Enzyme:
的人
let containerStyle = wrapper.find('#item-id').get(0).props.style;
expect(containerStyle).toHaveProperty('opacity', '1'); // ('propert', 'value')
注:
- 找到returns一个
ShallowWrapper
所以我们需要.get(0)
第一个匹配的元素
.props
在这个实例中是一个属性而不是一个函数
- jest 使用
toHaveProperty
而不是 to.have.property
这对我也适用。
expect(containerStyle.getDOMNode()).toHaveStyle('opacity : 0');
我不得不这样做来替换
expect(getComputedStyle(checkbox.getDOMNode()).getPropertyValue('opacity')).toBe('0');
当我 运行 在我的 Intellij IDE 中进行本地测试时,它起作用了。然而,当我 运行 它使用 npm t
它失败了。一定与 getComputedStyle
在不同场景中的计算方式有关。
toHaveStyle
在两个
工作
我不知道 Enzyme 是否随着最近的版本发生了变化,但我需要在 prop 之后加上括号才能使最佳答案生效。
containerStyle = container.get(0).props().style;
const node = wrapper.find(Element);
//Checking border property
expect(getComputedStyle(node.getDOMNode()).getPropertyValue('border')).toBe('2px solid red');
我正在尝试测试 React 组件的样式属性。在测试中获取样式参数的最佳方法是什么?
目前,我最好的选择是测试 HTML 是否包含字符串,但我认为还有更好的选择。
案例:
it('Should render large image when desktop', () => {
const dummyUrl = 'http://dummyUrl';
const wrapper = shallow(
<MockedStore
initialState={{
app: fromJS({ browser: { desktop: true } }),
}}
>
<LandingHero bigImage={dummyUrl} />
</MockedStore>
);
});
要测试的组件是:
// @flow
import React, { Component } from 'react';
import gc from 'styles/core.scss';
import $ from 'jquery';
import DownloadButton from 'components/DownloadButton';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import DownArrow from 'components/DownArrow';
import { connect } from 'react-redux';
import type { Map } from 'immutable';
import c from './styles.scss';
@withStyles([gc, c])
@connect(({ app }) => ({ app }))
class LandingHero extends Component {
componentDidMount() {
if ($(window).height() > 0) { // Necesary for webpack dev server
$(this.hero).css('height', $(window).height() - 46);
}
}
hero: HTMLElement;
props: {
app: Map<string, any>,
copy: string,
secondaryText: string,
thirdText: string,
bigImage?: string,
smallImage: string,
}
render() {
const { copy, secondaryText, thirdText } = this.props;
const browser = this.props.app.has('browser') ? this.props.app.get('browser') : {};
const backgroundImage = browser.desktop ? this.props.bigImage : this.props.smallImage;
return (
<div
className={`${c.hero} ${gc.textCenter}` +
` ${gc.alignMiddle} ${gc.alignCenter} ${gc.row} ${gc.expanded}`}
ref={(hero) => { this.hero = hero; }}
style={{
margin: 0,
position: 'relative',
background: `linear-gradient(to bottom, rgba($ixdarkprimary, .3), rgba($ixdarkprimary, .3)), url(${backgroundImage || ''})`,
}}
>
<div className={`${gc.row} ${gc.alignCenter} ${gc.alignMiddle} ${gc.column} ${gc.medium10}`}>
<div className={`${gc.textCenter}`}>
<div
className={`${gc.white} ${c.mainText} ${c.copy}`}
>
{ copy }
</div>
<div className={`${gc.small6} ${gc.smallOffset3} ${gc.medium4} ${gc.mediumOffset4}`} style={{ marginBottom: 45 }}>
<DownloadButton />
</div>
<div className={`${gc.white} ${gc.fontBold} ${gc.font24}`}>{secondaryText}</div>
<p className={`${gc.white} ${gc.font20}`}>{thirdText}</p>
</div>
<DownArrow goTo="#content" />
</div>
</div>
);
}
}
export default LandingHero;
看看 chaiEnzyme,它提供了一个方便的小断言,您可以将其与 chai 一起使用来检查包装器是否具有特定样式 (https://github.com/producthunt/chai-enzyme#stylekey-val),这应该有助于使您的测试看起来更清晰一些。
您可以使用this方法。它 returns ReactElement.
let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');
expect(component.find('#item-id').prop('style')).to.deep.equal({display: 'none'})
稍微阐述一下别人的答案:
expect(component.find('#item-id').prop('style')).toHaveProperty('backgroundSize', '100%');
这将检查 #item-id
的 style
属性。这个道具是一个对象,这里 toHaveProperty
匹配器检查这个对象是否包含 backgroundSize
属性 以及它的值是否为 100%
。
这样其他样式属性将被忽略。
如果你使用 jest-styled-components 那么你可以使用 toHaveStyleRule
如下:
expect(component.find('#item-id')).toHaveStyleRule('opacity', 'red');
const elem = wrapper.find(Element);
expect(getComputedStyle(elem.getDOMNode()).getPropertyValue('opacity')).toBe('0.4');
补充一下,下面的props()
方法也可以。
https://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html
let containerStyleOpacity = container.get(0).props().style.opacity;
expect(containerStyleOpacity).to.be.equal('1');
对我来说,这是几个答案的混搭。 对于那些也使用 Jest / Enzyme:
的人let containerStyle = wrapper.find('#item-id').get(0).props.style;
expect(containerStyle).toHaveProperty('opacity', '1'); // ('propert', 'value')
注:
- 找到returns一个
ShallowWrapper
所以我们需要.get(0)
第一个匹配的元素 .props
在这个实例中是一个属性而不是一个函数- jest 使用
toHaveProperty
而不是to.have.property
这对我也适用。
expect(containerStyle.getDOMNode()).toHaveStyle('opacity : 0');
我不得不这样做来替换
expect(getComputedStyle(checkbox.getDOMNode()).getPropertyValue('opacity')).toBe('0');
当我 运行 在我的 Intellij IDE 中进行本地测试时,它起作用了。然而,当我 运行 它使用 npm t
它失败了。一定与 getComputedStyle
在不同场景中的计算方式有关。
toHaveStyle
在两个
我不知道 Enzyme 是否随着最近的版本发生了变化,但我需要在 prop 之后加上括号才能使最佳答案生效。
containerStyle = container.get(0).props().style;
const node = wrapper.find(Element);
//Checking border property
expect(getComputedStyle(node.getDOMNode()).getPropertyValue('border')).toBe('2px solid red');