如何使用 Enzyme 测试 React 组件属性的样式
Posted
技术标签:
【中文标题】如何使用 Enzyme 测试 React 组件属性的样式【英文标题】:How to test style for a React component attribute with Enzyme 【发布时间】:2017-04-09 07:34:03 【问题描述】:我正在尝试测试 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;
【问题讨论】:
嘿 jacefarm 为了使用 sass(scss),您开玩笑的配置是什么?我的意思是我有以下 ` "moduleNameMapper": "\\.(scss|css)$": "Cannot read property 'textCenter' of undefined
,因为$gc.textCenter
import ConnLandingHero, LandingHero from "../LandingHero";
这为我们的团队节省了很多时间。
【参考方案1】:
看看 chaiEnzyme,它提供了一个方便的小断言,您可以使用 chai 来检查包装器是否具有特定样式 (https://github.com/producthunt/chai-enzyme#stylekey-val),应该有助于使您的测试看起来更简洁。
【讨论】:
【参考方案2】:您可以使用this 方法。它返回 ReactElement。
let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');
【讨论】:
对于那些使用 Jest 的人,请注意它应该是expect(...).toHaveProperty(...)
。
应该是container.get(0).props.style
这些都不适合我。 wrapper.get(0).style
返回 undefined 以及 wrapper.get(0).props.style
。
这只有在 style 是一个 react prop 时才有效,就像 inline-styling 的情况一样
尝试使用wrapper.props().style
,就我而言,我直接使用props()
摆脱了get(0)
,它给了我所需的style
属性【参考方案3】:
expect(component.find('#item-id').prop('style')).to.deep.equal(display: 'none')
【讨论】:
深在这里非常重要,thanx【参考方案4】:稍微详细说明其他人的答案:
expect(component.find('#item-id').prop('style')).toHaveProperty('backgroundSize', '100%');
这将检查#item-id
的style
属性。这个道具是一个对象,这里toHaveProperty
匹配器检查这个对象是否包含backgroundSize
属性以及它的值是否为100%
。
这样会忽略其他样式属性。
【讨论】:
【参考方案5】:如果您使用jest-styled-components,那么您可以使用toHaveStyleRule
,如下所示:
expect(component.find('#item-id')).toHaveStyleRule('opacity', 'red');
【讨论】:
【参考方案6】:const elem = wrapper.find(Element);
expect(getComputedStyle(elem.getDOMNode()).getPropertyValue('opacity')).toBe('0.4');
【讨论】:
如果你想断言应用于特定元素的外部 CSS 样式,这是正确的答案——这与作为道具传递的内联 CSS 样式等相反。 完美运行。太感谢了。这应该是公认的答案!【参考方案7】:我想补充一点,下面的props()
方法也可以使用。
https://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html
let containerStyleOpacity = container.get(0).props().style.opacity;
expect(containerStyleOpacity).to.be.equal('1');
【讨论】:
【参考方案8】:对我来说,这是几个答案的混搭。 对于那些也使用 Jest / Enzyme 的人:
let containerStyle = wrapper.find('#item-id').get(0).props.style;
expect(containerStyle).toHaveProperty('opacity', '1'); // ('propert', 'value')
注意:
find 返回一个ShallowWrapper
所以我们需要.get(0)
第一个匹配元素
.props
在此实例中是属性而不是函数
开玩笑使用toHaveProperty
而不是to.have.property
【讨论】:
【参考方案9】:这也适用于我。
expect(containerStyle.getDOMNode()).toHaveStyle('opacity : 0');
我不得不这样做来替换
expect(getComputedStyle(checkbox.getDOMNode()).getPropertyValue('opacity')).toBe('0');
当我在我的 Intellij IDE 中本地运行测试时,它起作用了。但是,当我使用 npm t
运行它时,它失败了。必须与 getComputedStyle
在不同场景中的计算方式有关。
toHaveStyle
在这两个地方都工作过 ?
【讨论】:
【参考方案10】:我不知道 Enzyme 是否在最近的版本中发生了变化,但我需要在 props 后面加上括号才能获得最佳答案。
containerStyle = container.get(0).props().style;
【讨论】:
【参考方案11】:const node = wrapper.find(Element);
//Checking border property
expect(getComputedStyle(node.getDOMNode()).getPropertyValue('border')).toBe('2px solid red');
【讨论】:
请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。 相同到already existing本页旧答案以上是关于如何使用 Enzyme 测试 React 组件属性的样式的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React with Jest 和 Enzyme 中测试表单提交?无法读取未定义的属性“preventDefault”
如何使用 Jest/Enzyme 在功能性 React 组件中测试 lambda 函数?
如何使用 Jest 和/或 Enzyme 测试由 React 组件呈现的样式和媒体查询
如何使用 Jest 和 Enzyme 测试具有 Router、Redux 和两个 HOC 的 React 组件?
如何覆盖 react-hooks 组件内的函数测试 - Enzyme/Jest
Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件