我正在使用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和一般的测试组件都很新。任何帮助或示例将不胜感激。
请注意:我对此组件的其他测试正在通过。我相信导入和设置都是正确的。
答案 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)