2016-11-24 98 views
10

我正在尝试测试React组件的样式属性。在测试中获得风格参数的最佳方式是什么?如何使用酶测试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; 
+0

hey jacefarm你为了使用sass(s​​css)而使用的配置是什么?我的意思是我有以下''moduleNameMapper“:\\。(scss | css)$”:“ /src/sassMockForJest.js” },但是当我使用属性时,例如I使用像你一样的组件我会看到'因为'$ {gc.textCenter}' –

回答

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" 
15

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

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

'无法读取未定义的属性'textCenter'对于那些使用Jest的,请注意它应该是'expect(...).toHaveProperty ...)'而不是。 –

4

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

+0

这里比deepx很重要 –

2

稍微详细阐述了别人的答案:

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

这将检查style道具#item-id。这个道具是一个对象,这里toHaveProperty匹配器检查这个对象是否包含backgroundSize属性,如果它的值是100%

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