Как протестировать стиль для атрибута компонента React с помощью 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;

person cristian camilo cedeño gallego    schedule 24.11.2016    source источник
comment
Эй, jacefarm, какую конфигурацию вы используете для шутки, чтобы использовать sass (scss)? Я имею в виду, что у меня есть следующий `moduleNameMapper: {\\. (Scss | css) $: ‹rootDir› /src/sassMockForJest.js}, но я получал неопределенные ошибки при использовании свойств, например, если я использовал тот же компонент, что и вы Я бы увидел Cannot read property 'textCenter' of undefined, потому что ${gc.textCenter}   -  person heriberto perez    schedule 19.07.2017
comment
Эй, вы можете избавиться от своего фиктивного магазина, также экспортировав свой класс. Вы получаете: import ConnLandingHero, { LandingHero } from "../LandingHero"; Это сэкономило нашей команде много времени.   -  person taystack    schedule 06.08.2019


Ответы (11)


Вы можете использовать этот метод. Он возвращает ReactElement.

let containerStyle = container.get(0).style;
expect(containerStyle).to.have.property('opacity', '1');
person visortelle    schedule 30.03.2017
comment
Для тех, кто использует Jest, обратите внимание, что вместо этого должно быть expect(...).toHaveProperty(...). - person Yangshun Tay; 02.01.2018
comment
Это должно быть container.get(0).props.style - person user3142695; 29.05.2018
comment
Jest может получить стиль css? - person shinriyo; 25.10.2018
comment
Все это у меня не работает. wrapper.get(0).style возвращает undefined, а также wrapper.get(0).props.style. - person 10000RubyPools; 11.03.2019
comment
это будет работать только в том случае, если style является опорой реакции, как в случае встроенного стиля - person redbandit; 03.09.2019
comment
То же самое, ничего из вышеперечисленного не сработало, но это - ›wrapper.get(0).props.style сработало для меня, когда свойство style назначено компоненту - person Siddhartha Chowdhury; 01.09.2020
comment
попробуйте использовать wrapper.props().style, в моем случае я избавился от get(0), напрямую используя props(), и он дал мне необходимое свойство style - person Dawood Valeed; 10.06.2021

Немного уточняя ответы других:

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

Это проверит style опору #item-id. Эта опора является объектом, и здесь toHaveProperty сопоставитель проверяет, содержит ли этот объект свойство backgroundSize и равно ли его значение 100%.

Таким образом игнорируются другие свойства стиля.

person Neurotransmitter    schedule 29.12.2017

Если вы используете jest-styled-components, вы можете использовать toHaveStyleRule следующим образом :

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

person DenisH    schedule 01.06.2018

Взгляните на chaiEnzyme, который предоставляет удобное небольшое утверждение, которое вы можете использовать с chai, чтобы проверить, имеет ли оболочка определенный стиль (https://github.com/producthunt/chai-enzyme#stylekey-val), должно помочь сделать ваши тесты немного чище.

person Ben Hare    schedule 14.12.2016

Для меня это была смесь нескольких ответов. Для тех, кто также использует Jest / Enzyme:

let containerStyle = wrapper.find('#item-id').get(0).props.style;

expect(containerStyle).toHaveProperty('opacity', '1'); // ('propert', 'value')

Примечание:

  • find возвращает ShallowWrapper, поэтому нам нужно .get(0) первый соответствующий элемент
  • .props в данном случае атрибут, а не функция
  • jest использует toHaveProperty, а не to.have.property
person Kitson    schedule 13.05.2020

Хочу добавить, что также можно использовать следующий метод props(). https://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html

let containerStyleOpacity = container.get(0).props().style.opacity; expect(containerStyleOpacity).to.be.equal('1');

person Sark Peha    schedule 09.10.2019

Это работает и для меня.

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

Мне пришлось это сделать, чтобы заменить

expect(getComputedStyle(checkbox.getDOMNode()).getPropertyValue('opacity')).toBe('0');

который работал, когда я запускал тест локально в своей Intellij IDE. Однако когда я запустил его с помощью npm t, это не удалось. Должно быть какое-то отношение к тому, как getComputedStyle вычислялся в разных сценариях.

toHaveStyle работал в обоих ????

person Simon Long    schedule 18.06.2020

Я не знаю, изменился ли Enzyme в последних версиях, но мне нужны были скобки после реквизита, чтобы получить лучший ответ.

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

person feraleyebrows    schedule 14.10.2020

person    schedule
comment
это правильный ответ, если вы хотите утверждать внешний стиль CSS, применяемый к конкретному элементу, - в отличие от встроенных стилей CSS, передаваемых как реквизиты и т. д. - person revelt; 03.04.2020
comment
Прекрасно работает. Большое спасибо. Это должен быть принятый ответ! - person Simon Long; 17.06.2020

person    schedule
comment
Глубокий здесь очень важен, спасибо - person Hamed Minaee; 01.03.2018

person    schedule
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением обычно более полезны и качественнее, и с большей вероятностью получат положительные отзывы. - person Mark Rotteveel; 22.12.2020