Reputation: 547
Inside a <MyComponent>
component I am using react-responsive
<MediaQuery>
components to distinguish between rendering mobile and desktop content.
export class MyComponent extends React.Component {
//...
render() {
<MediaQuery query="(max-width: 600)">
<div className="inside-mobile">mobile view</div>
</MediaQuery>
}
}
I want to test the HTML inside <MyComponent>
's render()
using enzyme
, but can't seem to dive into the child elements of <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)
}
A console.log(wrapper.debug())
shows that nothing inside <MediaQuery>
is being rendered, though.
I'm guessing in a test (with no actual browser) window.width
is not set which leads to the <MediaQuery>
component not rendering anything.
What I want to do:
I want to be able to test <MyComponent>
's content using enzyme
with react-responsive
(or something similar such as react-media
) to deal with mobile vs desktop viewports.
Things I've tried:
enzyme
's shallow
with dive()
instead of mount
, to no avail.react-media
's <Media>
instead of react-responsive
's <MediaQuery>
, which seems to set window.matchMedia()
to true by default. However, that's not working either. console.log(wrapper.debug())
shows:
<MyComponent content={{...}}>
<Media query="(min-width: 600px)" defaultMatches={true} />
</MyComponent>
Upvotes: 2
Views: 2279
Reputation: 547
I found a working solution, using react-media instead of react-responsive, by mocking window.matchMedia
so that matches
is set to true
during the test:
Create specific media components for different viewports:
const Mobile = ({ children, content }) => <Media query="(max-width: 600px)" children={children}>{matches => matches ? content : "" }</Media>;
const Desktop = ...
Use specific media component:
<MyComponent>
<Mobile content={
<div className="mobile">I'm mobile</div>
}/>
<Desktop content={...}/>
</MyComponent>
Test content per viewport:
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");
});
});
Upvotes: 2