2016-11-24 94 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%

這樣,其他樣式屬性將被忽略。