2

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

export class MyComponent extends React.Component {

  //...

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

我想测试 HTML 里面<MyComponent>render()using 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)
}

但是, Aconsole.log(wrapper.debug())表明内部没有任何<MediaQuery>内容被渲染。我猜在测试中(没有实际的浏览器)window.width没有设置导致<MediaQuery>组件不渲染任何东西。

我想做的事:

我希望能够<MyComponent>使用enzymewith react-responsive(或类似的东西,例如react-media)来测试移动和桌面视口的内容。

我尝试过的事情:

  • 通过使用enzyme's shallowwithdive()而不是 来规避这一点mount,但无济于事。
  • 使用react-media's<Media>而不是react-responsive's <MediaQuery>,默认情况下似乎设置window.matchMedia()为 true 。但是,这也不起作用。

console.log(wrapper.debug())显示:

<MyComponent content={{...}}>
    <Media query="(min-width: 600px)" defaultMatches={true} />
</MyComponent>
4

1 回答 1

1

我通过模拟找到了一个工作解决方案,使用react-media而不是react-responsivewindow.matchMedia以便在测试期间matches设置为true

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

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");
    });
});
于 2018-07-26T13:54:08.160 回答