如何测试反应敏感标签内的React组件

时间:2018-07-09 09:20:09

标签: reactjs unit-testing media-queries enzyme chai-enzyme

<MyComponent>组件内部,我正在使用react-responsive <MediaQuery>组件来区分呈现移动内容和桌面内容。

export class MyComponent extends React.Component {

  //...

    render() {
      <MediaQuery query="(max-width: 600)">
        <div className="inside-mobile">mobile view</div>
      </MediaQuery>
    }
}

我想使用<MyComponent>测试render()的{​​{1}}内部的HTML,但似乎无法深入研究enzyme的子元素:

<MediaQuery>

it('should dive into <MediaQuery>', () => { const wrapper = mount(<Provider store={mockedStore}><MyComponent/></Provider>) const actual = wrapper.getDOMNode().querySelectorAll(".inside-mobile") expect(actual).to.have.length(1) } 表示console.log(wrapper.debug())内部没有任何内容被渲染。 我猜在一个测试中(没有实际的浏览器)未设置<MediaQuery>,这导致window.width组件未呈现任何内容。

我想做什么:

我希望能够使用<MediaQuery><MyComponent>(或类似enzyme之类的react-responsive来测试react-media的内容,以处理移动视口与桌面视口。

我尝试过的事情:

  • 通过将enzyme的{​​{1}}与shallow而不是dive()一起使用来规避这一点。
  • 使用react-mediamount代替<Media>的{​​{1}},这似乎默认将window.matchMedia()设置为true。但是,这也不起作用。

react-responsive显示:

<MediaQuery>

1 个答案:

答案 0 :(得分:1)

我通过模拟window.matchMedia从而使用react-media而不是react-responsive找到了一个可行的解决方案,以便在测试过程中将matches设置为true:< / p>

为不同的视口创建特定的媒体组件:

const Mobile = ({ children, content }) => <Media query="(max-width: 600px)" children={children}>{matches => matches ? content : "" }</Media>;
const Desktop = ...

使用特定的媒体组件:

<MyComponent>
    <Mobile content={
        <div className="mobile">I'm mobile</div>
    }/>
    <Desktop content={...}/>
</MyComponent>

每个视口的测试内容:

const createMockMediaMatcher = matches => () => ({
    matches,
    addListener: () => {},
    removeListener: () => {}
});

describe('MyComponent', () => {
    beforeEach(() => {
        window.matchMedia = createMockMediaMatcher(true);
    });

    it('should display the correct text on mobile', () => {

        const wrapper = shallow(<MyComponent/>);
        const mobileView = wrapper.find(Mobile).shallow().dive();
        const actual = mobileView.find(".mobile").text();

        expect(actual).to.equal("I'm mobile");
    });
});