Jest-styled-components: No style rules found on passed Component

Created on 30 Oct 2018  路  3Comments  路  Source: styled-components/jest-styled-components

I am trying to test my component with jest and enzyme but unfortunately it can't find the style.

Here is the component:

interface StyledProps {
  fluid: boolean;
}

const Button = styled(TouchableOpacity)<StyledProps>`
  align-items: center;
  justify-content: center;
  ${({ fluid }: StyledProps) => fluid && { width: '100%' }};
`;

const ButtonText = (styled as any).Text({
  color: #fff,
  fontSize: 16,
});

const GradientButton = ({ testID, onPress, title, fluid = false }: GradientButtonProps) => {
  return (
    <Button fluid={fluid} {...testLabel(testID)} onPress={onPress}>
      <ButtonText>{title}</ButtonText>
    </Button>
  );
};

export default GradientButton;

And here is the test:

let wrapper: ShallowWrapper;
const component = <GradientButton testID={TEST_ID} title={TITLE} onPress={onPressSpy} />;
beforeEach(() => {
  wrapper = shallow(component);
});

describe('<GradientButton />', () => {
  it('renders fluid', () => {
    wrapper.setProps({
       fluid: true,
    })
    expect(wrapper).toHaveStyleRule('width', '100%');
  });
});

Which gives me: No style rules found on passed Component

package.json:

    "react": "16.5.1",
    "styled-components": "^3.4.10",
    "react-native": "0.57.1",
    "jest-styled-components": "^6.2.2",
react native

Most helpful comment

Thanks for opening this issue, @jmacioszek.

The test says "No style rules found on passed Component" because you are shallow rendering and the children components don't get resolved.
If you use mount, the tests will work.

I hope this helps.

All 3 comments

Thanks for opening this issue, @jmacioszek.

The test says "No style rules found on passed Component" because you are shallow rendering and the children components don't get resolved.
If you use mount, the tests will work.

I hope this helps.

@MicheleBertoli Thanks for your reply.

I've changed the code to work with mount (please note, it's react-native)

Now my test look as follows:

const component = (
  <GradientButton testID={TEST_ID} title={TITLE} onPress={onPressSpy} fluid={true} />
);

describe('..', () => {
   it('renders as fluid', () => {
    const wrapper = mount(component);
    expect(wrapper).toHaveStyleRule('width', '100%');
  });
})

That unfortunately throws TypeError: Cannot read property '0' of undefined

@MicheleBertoli

TypeError: Cannot read property '0' of undefined was an issue on my side and bad styles passed to ButtonText.

Anyway, I have made mount to work in the following way (inside of jest setup file):

require('react-native-mock-render/mock');

const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { document } = new JSDOM('').window;
const g = global as any;

g.document = document;
g.window = document.defaultView;
Object.keys(document.defaultView).forEach(property => {
  if (typeof g[property] === 'undefined') {
    g[property] = document.defaultView[property];
  }
});

Then the same test:

const component = (
  <GradientButton testID={TEST_ID} title={TITLE} onPress={onPressSpy} fluid={true} />
);

describe('..', () => {
   it('renders as fluid', () => {
    const wrapper = mount(component);
    expect(wrapper).toHaveStyleRule('width', '100%');
  });
})

Gives me the same error No style rules found on passed Component

I have also tried that way:

describe('..', () => {
   it('renders as fluid', () => {
    const wrapper = mount(component);
    expect(wrapper.find('TouchableOpacity').toHaveStyleRule('width', '100%');
  });
})

What gives the same error.

However snapshot looks like that:

   <TouchableOpacity
     activeOpacity={0.2}
     fluid={true}
     onPress={[MockFunction]}
     style={
        Array [
          Object {
            "alignItems": "center",
            "justifyContent": "center",
            "width": "100%",
          },
         undefined,
      ]
    }
    testID="GradientButton"
  >

Was this page helpful?
0 / 5 - 0 ratings