styled-components / jest-styled-components

🔧 💅 Jest utilities for Styled Components
MIT License
1.58k stars 145 forks source link

100% test coverage when using snapshots #75

Closed josokinas closed 7 years ago

josokinas commented 7 years ago

I use Styled Components to add styling without leaking props, something like this:

import React from 'react'
import StyledComponents from 'styled-components'
import omit from 'lodash/omit'

export const TestComponent = StyledComponents((props) => (
  <div
    {...omit(props, [
      'display'
    ])}
  />
))`
  display: ${props => props.display};
`

Then, I write a test:

import React from 'react'

import 'jest-styled-components'
import { shallow } from 'enzyme'
import toJson from 'enzyme-to-json'

import { TestComponent } from '../TestComponent'

describe('`TestComponent` component', () => {
  it('should not set any properties by default', () => {
    const wrapper = shallow(<TestComponent />)
    expect(toJson(wrapper)).toMatchSnapshot()
  })

  describe('`display` property', () => {
    it('should be able to set as `block`', () => {
      const wrapper = shallow(<TestComponent display='block' />)
      expect(toJson(wrapper)).toMatchSnapshot()
    })
  })
})

This will do all the necessary testing, however code coverage will show the following report:

Code coverage for TestComponent

How should I overcome this to reach 100% test coverage?

MicheleBertoli commented 7 years ago

Thanks for opening the issue, @josokinas. This is interesting. I'm not a coverage expert but I'll look into this soon

MicheleBertoli commented 7 years ago

I run your code and I found out the "problem" is due to the shallow rendering. In fact, with shallow rendering, only the wrapper component is rendered and the div never gets executed.

If you try with mount, it works as expected.

screen shot 2017-09-10 at 08 41 06

I hope this helps.

josokinas commented 7 years ago

Thanks.

This actually solves the "problem" by introducing another one.

When using mount the whole component (with all children) gets rendered for the snapshot. It's especially problematic when styling 3rd party components - updating that library would fail tests for these snapshots, but most likely does not mean something's breaking on local code. Also, it is then required to mock the document with e.g. jsdom or run tests inside the browser - which I also tend to avoid, especially for simple components.

Ideally it would be good to have a better implementation for such case, where you would not want props to be passed to the component you're styling.

MicheleBertoli commented 7 years ago

I understand your concerns, even though I usually tend to run snapshots on leaf components (that don't have children). The "issue" you described affect snapshot testing with React in general, and it's not related to this package.

If you still want to use shallow rendering and get 100% coverage, you can use dive as follows:

const wrapper = shallow(<TestComponent />).dive()

I hope this helps.