如何使用酶测试React-Responsive组件?

时间:2016-08-25 13:08:49

标签: reactjs 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并使Header成为AppContainer的直接子项,那么测试就会通过。

我想这不是一个错误,因为我对Enzyme和一般的测试组件都很新。任何帮助或示例将不胜感激。

请注意:我对此组件的其他测试正在通过。我相信导入和设置都是正确的。

4 个答案:

答案 0 :(得分:2)

问题是Media Query正在寻找与jsdom未定义的window.matchMedia。

在这种情况下,我需要使用Server Side Rendering实现。但是,这需要宽度的静态值,这会破坏响应性。

我的解决方案是在测试虚拟DOM上设置一个全局变量。

window.testMediaQueryValues = {width:740};

然后MediaQuery可以访问它们,如果它们在那里:

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

如果未设置变量,则会忽略空值,并且Component会照常渲染。

非常感谢@Contra的帮助和超级图书馆

答案 1 :(得分:1)

对我有用的是使用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; 

答案 2 :(得分:0)

尝试在单元测试中模拟 react-responsive 依赖项。使用Webpack,我使用inject-loader向模块注入测试依赖项。您可以使用&#34; inject-loader&#34;导入组件。并传递它想要覆盖的依赖项。

示例:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div contenteditable="true" id="Box"></div>

<button>Show HTML</button>

然后

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

然后,您可以测试特定的媒体查询

答案 3 :(得分:0)

我能够使用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)