0
votes

I have a React component named Product which looks like this:

<div>
            <Wrapper>
                <Heading>{props.headerText}</Heading>
                <Service>({props.items.length})</Service>
            </Wrapper>
            {props.items !== undefined && props.items.length > 0 ? (
                <TableWrapper>
                    {props.items &&
                        props.items.length > 0 && (
                            <DataTable paginationSize={props.paginationSize}>
                                <DataTable.Heading accessor="name"> Name </DataTable.Heading>
                                <DataTable.Heading accessor="id"> Service ID </DataTable.Heading>
                                <DataTable.Heading accessor="type"> Access </DataTable.Heading>
                                <DataTable.Heading accessor="band"> Band </DataTable.Heading>
                                <DataTable.Heading accessor="noUsers"> Users </DataTable.Heading>

                                {props.tableItems.map((p, i) => {
                                    return <DataTable.Row key={i} data={p} />;
                                })}
                            </DataTable>
                        )}
                </TableWrapper>
            ) : (
                <NoMessage>{props.noItemMessage}</NoMessage>
            )}
        </div>

where Wrapper, Heading, Service, TableWrapper are styled-components. I am trying to test this component using Jest and Enzyme to check if the headerText prop is being rendered correctly.The below given code is how I am trying to write my test case:

 test("header text is being passed through correctly", () => {
        const wrapper = mount(
            <Product items={data} headerText="Service" paginationSize="5" noItemMessage="No results found" />
        );
        expect(wrapper.find(HeaderText).text()).toEqual("Service");

but I get this error as:

TypeError: Cannot read property 'blue' of undefined

      at Object.<anonymous>.exports.RightArrow.Icons.RightArrow.extend.props (src/lib/DataTable.js:149:129)

and the line 149 in DataTable.js is:

color: ${props => props.theme.secondary.blue};

I am not able to figure out why I am getting this error. Can anyone please guide me with this issue? I am just trying to check if the headerText is rendered properly from the props.

2

2 Answers

1
votes

to get ride of add theme as props in your wrapper

<Product items={data} theme={{secondary: {blue: ''}}} headerText="Service" paginationSize="5" noItemMessage="No results found" />

or mock it

import { createSpy } from 'expect'; const theme = createSpy(); <Product items={data} theme={theme} headerText="Service" paginationSize="5" noItemMessage="No results found" />

0
votes

we can use the themeProvider of styled-componnets to create a wrapper around the shallow or mount methods of enzyme, like below:

import { ThemeProvider } from 'styled-components';

const mountWithTheme = (children, theme={}, options = {}) => {
 const wrapper = mount(<ThemeProvider theme={theme}>{children}</ThemeProvider>, options);
 return wrapper.mount({});
};

test("header text is being passed through correctly", () => {
  const wrapper =  mountWithTheme(<Product items={data} headerText="Service" paginationSize="5" noItemMessage="No results found" />,
{ secondary: { blue: 'blue' } }); 
// we passed the theme we want as an argument to the mountWithTheme method
  expect(wrapper.find(HeaderText).text()).toEqual("Service");
});


It will be better to pull out the utils mountWithTheme and ShallowWithTheme to a different file so that it can be reused, and also as a suggestion, you can create a mockTheme file which contains some default themes which can be passed to these wrappers instead of manually passing the theme each time we are consuming these utils.

More more information, visit below link: https://github.com/styled-components/styled-components/issues/1319