Jamie Nordmeyer
Jamie Nordmeyer

Reputation: 607

Enzyme shallow testing with Material-UI

I'm using Material UI in my application. I have the following component that I want to test for a valid disclaimer text (notice that I'm using the withStyles HOC here):

import React from 'react';
import { object } from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import { Typography } from '@material-ui/core';

const headerBarHeight = 64;

const styles = () => ({
    disclaimer: {
        position: 'absolute',
        bottom: headerBarHeight,
        padding: '0 0 5px 10px'
    }
});

const Disclaimer = props => {
    const { classes } = props;

    return (
        <div className={classes.disclaimer}>
            <Typography gutterBottom noWrap>
                Copyright StaticSphere { new Date().getFullYear() }
            </Typography>
        </div>
    );
};

Disclaimer.propTypes = {
    classes: object.isRequired
};

export default withStyles(styles)(Disclaimer);

What I'm trying to do is write a test that verifies the year is considered correctly:

import React from 'react';
import { shallow } from 'enzyme';
import { Typography } from '@material-ui/core';

import Disclaimer from 'components/Shell/Disclaimer';

describe('Disclaimer', () => {
    it('displays the proper year', () => {
        var component = shallow(
            <Disclaimer />
        );

        var year = new Date().getFullYear();
        var text = component.find(Typography).text();

        expect(text).toBe(`Copyright StaticSphere ${year}`);
    });
});

This doesn't work. The test complains that it can't find the Typography component. Looking at the documentation, this is expected, since Typography isn't the root component. When I change the test to use mount, everything works.

That said, I've read that I should try and use shallow wherever possible, since mount creates an actual DOM to work with. So, is there a better way to deal with this? I've spent a day on the internet, and so far, haven't found a good example of a better way.

Thanks!

Upvotes: 4

Views: 3726

Answers (2)

Sakhi Mansoor
Sakhi Mansoor

Reputation: 8102

When you're using HOC we need to use WrappedComponent to get wrapped jsx inside it.

 var component = shallow(
        <Disclaimer.WrappedComponent />
    ).dive(); 

dive() will further shallow re-render Components like in our case it'sTypegraphy`.

You can try this without using dive()

Apart from this you can simply access Typography with:

var text = component.find('withStyles(Typography)').text();

I hope this helps, let me know if the issue still persists

Upvotes: -2

byverdu
byverdu

Reputation: 393

OMG.... took me a while to make it work too but I've found a working example in the repo's page. material-ui has a wrapper on top of enzyme's shallow and mount that allows you to dive the component that you want to test.

shallow = createShallow({ dive: true }); made my day.

This is the config that I followed, also in my case I had to call component.update(); after doing some operations in other to see my state updated.

Upvotes: 6

Related Questions