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

时间:2016-11-24 23:41:49

标签: reactjs 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;

12 个答案:

答案 0 :(得分:33)

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

let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');

答案 1 :(得分:16)

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

答案 2 :(得分:14)

稍微详细说明其他人&#39;答案:

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

这会检查style的{​​{1}}道具。此prop是一个对象,此处#item-id匹配器检查此对象是否包含toHaveProperty属性,以及其值是否为backgroundSize

这样会忽略其他样式属性。

答案 3 :(得分:3)

看看chaiEnzyme,它提供了一个方便的小断言,你可以用它来检查包装器是否有特定的样式(https://github.com/producthunt/chai-enzyme#stylekey-val),应该有助于让你的测试看起来更清洁。

答案 4 :(得分:3)

如果您使用jest-styled-components,则可以按如下方式使用toHaveStyleRule

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

答案 5 :(得分:2)

您可以尝试在regex值上使用.html()

const span = mount(<Test />).find('span');
expect(span.html().match(/style="([^"]*)"/i)[1]).toBe('color: #000;');

或获取任何其他属性:

const getAttr = ( html, name ) => html.match(new RegExp(`${name}="([^"]*)"`, 'i'))[1];
let type = getAttr('<input type="text" value=""/>', 'type');
console.log(type);  // "text"

答案 6 :(得分:1)

对我来说,这是一些答案的混搭。 对于也使用笑话/酶的人:

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

答案 7 :(得分:0)

const elem = wrapper.find(Element);
expect(getComputedStyle(elem.getDOMNode()).getPropertyValue('opacity')).toBe('0.4');

答案 8 :(得分:0)

我想补充一点,也可以使用以下ggplot() + geom_point(aes(x = year,y = boys, colour = 'Boys'),data=arbuthnot) + geom_point(aes(x = year,y = girls, colour = 'Girls'),data=arbuthnot,shape = 17) + xlab(label = 'Year') + ylab(label = 'Rate') 方法。 https://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html

props()

答案 9 :(得分:0)

这也对我有用。

save as

我必须这样做才能替换

expect(containerStyle.getDOMNode()).toHaveStyle('opacity : 0');

当我在Intellij IDE中本地运行测试时有效。但是,当我使用expect(getComputedStyle(checkbox.getDOMNode()).getPropertyValue('opacity')).toBe('0');运行它时,它失败了。必须与在不同情况下如何计算npm t有关。

getComputedStyle都在worked

答案 10 :(得分:0)

我不知道酶的最新版本是否已更改,但是我需要在括号后加上小括号,以获取最佳答案。

containerStyle = container.get(0).props().style;

答案 11 :(得分:0)

@EnvironmentObject