Как проверить реагирующие на реакцию компоненты с помощью Enzyme?

Я использую библиотеку React-Reponsive. https://github.com/contra/react-responsive

Я изо всех сил пытаюсь понять, как тестировать компоненты, вложенные в React-Responsive Media Query Components:

export default class AppContainer extends React.Component {
  render(){
    return(
      <MediaQuery minDeviceWidth={750}>
         <Header />
      </MediaQuery>
    );
  }
}

-

describe("AppContainer", () => {
  let App;
  let wrapper;
  beforeEach(() => {
    wrapper = mount(<Provider store={store}><AppContainer location={location} /></Provider>);
    App = wrapper.find(AppContainer);

  });
  it('to have a <Header /> component', () => { 
    console.log(App.debug());
    expect(App.find(Header)).to.have.length(1);
  });
}

Результат теста:

1) AppContainer to have a <Header /> component:
AssertionError: expected { Object (component, root, ...) } to have a length of 1 but got 0

Соответствующая часть вывода console.log:

<MediaQuery minDeviceWidth={750} values={{...}} />

Указывает, что заголовок действительно не отображается в дереве рендеринга. Однако, если я удалю MediaQuery и сделаю заголовок прямым потомком AppContainer, тест пройдет.

Я полагаю, что это не ошибка, поскольку я новичок в Enzyme и тестировании компонентов в целом. Любая помощь или примеры будут оценены.

Обратите внимание: другие тесты, которые у меня есть на этом компоненте, проходят нормально. Я уверен, что импорт и настройка верны.


person Dom Hede    schedule 25.08.2016    source источник
comment
Разве это не должно быть expect(App.find(MediaQuery)).to.have.length(1);   -  person vijayst    schedule 25.08.2016
comment
Да, это сработает для тестирования Media Query, но я ищу, как проверить заголовок в этом случае.   -  person Dom Hede    schedule 25.08.2016


Ответы (4)


Проблема заключалась в том, что Media Query ищет window.matchMedia, который с jsdom не определен.

В этом случае мне нужно было использовать реализацию рендеринга на стороне сервера. Однако для этого потребуется статическое значение ширины, что нарушит отзывчивость.

Мое решение - установить глобальную переменную в тестовой виртуальной DOM.

window.testMediaQueryValues = {width:740};

Затем MediaQuery сможет получить к ним доступ, если они есть:

<MediaQuery maxWidth={smallViewMaxWidth} values={window.testMediaQueryValues}>

В случае, когда переменная не установлена, нулевые значения игнорируются, и компонент отображается как обычно.

Большое спасибо @Contra за его помощь и супер библиотеку

person Dom Hede    schedule 26.08.2016
comment
Возможно, когда вы это писали, функция response-responseive была другой, но на сегодняшний день values не используется в контексте браузера. Значит, вам не нужно глобальное тестовое значение. Вместо этого вы можете передать опору, которая служит для сохранения. - person rodrigo-silveira; 25.02.2017
comment
@ rodrigo-silveira, ты можешь подробнее рассказать об этом? не уверен, что вы имеете в виду, говоря о передаче опоры для той же цели - person tscizzle; 05.08.2017
comment
Я думаю, что я имел в виду, что ваш компонент может принимать дополнительные опоры, такие как width или displayMode, которые он может использовать, чтобы решить, какой подкомпонент отображать, вместо того, чтобы полагаться на состояние окна, чтобы сообщить вам ширину области просмотра. - person rodrigo-silveira; 05.08.2017

У меня сработало добавление фиктивного компонента react-responsive с использованием каталога __mocks__. В основном создайте следующий файл в структуре каталогов:

-your-component

--component-using-media-query.js

--__mocks__

---react-responsive.js

Затем вы можете смоделировать компонент MediaQuery в файле react-responsive.js.

const MediaQuery = ({ children }) => children;

export default MediaQuery; 
person asulaiman    schedule 15.08.2018
comment
После нескольких часов пробных решений это сработало, и это так просто. - person Shane Beehler; 08.04.2020
comment
Это работает ... Но как добавить разную ширину? .. Прямо сейчас он отображает все ‹MediaQuery› в соответствии с макетом .. - person MontyGoldy; 19.07.2020

Я смог заставить его работать, используя react-responsive v7.0.0.

Данный:

<MediaQuery minDeviceWidth={750}>
  <Header />
</MediaQuery>

Следующие работы:

import { Context as ResponsiveContext } from 'react-responsive'
import { mount } from 'enzyme'

const wrappingComponent = ResponsiveContext.Provider
const wrappingComponentProps = { value: { width: 750 } }
const mountProps = { wrappingComponent, wrappingComponentProps }

const wrapper = mount(<AppContainer />, mountProps)

person Paweł Gościcki    schedule 05.08.2019

Попробуйте издеваться над зависимостью реагировать в своем модульном тесте. Работая с Webpack, я использую inject-loader для внедрения тестовых зависимостей в модули. Вы можете импортировать свой компонент с помощью «inject-loader» и передать ему, какие зависимости вы хотите перезаписать.

Пример:

import YourComponentInjector from 'inject-loader!../YourComponent.jsx';

а потом

class MediaQueryDesktopMock extends React.Component {
    render() {
      const {minDeviceWidth, children} = this.props;
      if(minDeviceWidth === 765) {
        return (<div>{children}</div>)
      }
      return <span/>;
    }
  }
  let YourComponentMock = YourComponentInjector({
    'react-responsive': MediaQueryDesktopMock
  });

затем вы можете протестировать определенные медиа-запросы

person Janusz Kacalak    schedule 25.08.2017