如何使用酶测试 React 组件属性的样式

IT技术 reactjs enzyme
2021-03-28 13:26:56

我正在尝试测试 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;
6个回答

您可以使用方法。它返回 ReactElement。

let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');
这些都不适合我。wrapper.get(0).style返回 undefined 以及wrapper.get(0).props.style.
2021-06-02 13:26:56
它应该是 container.get(0).props.style
2021-06-09 13:26:56
这仅在样式是内联样式的反应道具时才有效
2021-06-20 13:26:56
尝试使用wrapper.props().style,在我的情况下,我get(0)通过直接使用摆脱了props()它,它给了我所需的style属性
2021-06-20 13:26:56
对于那些使用 Jest 的人,请注意它应该是expect(...).toHaveProperty(...)
2021-06-21 13:26:56

稍微阐述一下别人的回答:

expect(component.find('#item-id').prop('style')).toHaveProperty('backgroundSize', '100%');

这将检查style的props#item-id这个 prop 是一个对象,在这里toHaveProperty匹配器检查这个对象是否包含backgroundSize属性以及它的值是否为100%.

这样其他样式属性将被忽略。

const elem = wrapper.find(Element);
expect(getComputedStyle(elem.getDOMNode()).getPropertyValue('opacity')).toBe('0.4');
完美运行。太感谢了。这应该是公认的答案!
2021-06-16 13:26:56
如果您想对应用于特定元素的外部 CSS 样式进行断言,这是正确的答案——这与作为道具等传递的内联 CSS 样式相反。
2021-06-17 13:26:56

expect(component.find('#item-id').prop('style')).to.deep.equal({display: 'none'})

深在这里非常重要thanx
2021-05-25 13:26:56

如果你使用jest-styled-components那么你可以使用toHaveStyleRule如下:

expect(component.find('#item-id')).toHaveStyleRule('opacity', 'red');