Test Styled Components
Learn how to test the styled-components using Jest.
We'll cover the following
Testing styled components using Jest
-
Let’s check how our tests are doing, starting with
Carousel
:$ npx jest src/tests/Carousel.test.js FAIL src/tests/Carousel.test.js Carousel ✓ renders a <div> (5ms) ✓ has an initial `slideIndex` of 0 (1ms) ✓ renders a CarouselButton labeled "Prev" (1ms) ✓ renders a CarouselButton labeled "Next" ✕ renders the current slide as a CarouselSlide (12ms) with a middle slide selected ✓ decrements `slideIndex` when Prev is clicked (4ms) ✓ increments `slideIndex` when Next is clicked (1ms) with the first slide selected ✓ wraps `slideIndex` to the max value when Prev is clicked with the last slide selected ✓ wraps `slideIndex` to the min value when Next is clicked (1ms) ● Carousel › renders the current slide as a CarouselSlide expect(received).toEqual(expected) Expected value to equal: {"attribution": "Uno Pizzeria", "description": "Slide 1", "imgUrl": "https://example.com/slide1.png"} Received: {"Img": ...}
Currently, the test implicitly assumes that
CarouselSlide
only has the props it receives fromCarousel
. That assumption no longer holds now thatCarouselSlide
has default props. -
Let’s update the test to account for those:
// src/tests/Carousel.test.js ... it('renders the current slide as a CarouselSlide', () => { let slideProps; slideProps = wrapper.find(CarouselSlide).props(); expect(slideProps).toEqual({ ...CarouselSlide.defaultProps, ...slides[0], }); wrapper.setState({ slideIndex: 1 }); slideProps = wrapper.find(CarouselSlide).props(); expect(slideProps).toEqual({ ...CarouselSlide.defaultProps, ...slides[1], }); })...
-
Now move on to the
CarouselSlide
tests:$ npx jest src/tests/CarouselSlide.test.js FAIL src/tests/CarouselSlide.test.js ● CarouselSlide › renders an <img> and a <figcaption> as children expect(received).toBe(expected) // Object.is equality Expected: "img" Received: {"$$typeof": Symbol(react.forward_ref), "attrs": [], ...} Difference: Comparing two different types of values. Expected string but received object. 20 | 21 | it('renders an <img> and a <figcaption> as children', () => { > 22 | expect(wrapper.childAt(0).type()).toBe('img'); | ^
This is a long winded way of saying that the first child of the CarouselSlide
wrapper element is no longer an <img>
element. Instead, it’s an instance of the Img
component. That component does render an <img>
element, but since this is a shallow test of CarouselSlide
, the behavior of other components is treated as an unknown.
The problem is we now have two components defined in CarouselSlide.js
: CarouselSlide
, and the locally defined Img
component. We need to expose Img
so we can reference the component in tests. For reasons that will become clear in the next section, let’s expose Img
by making it a prop. That is, CarouselSlide
will take a prop named Img
, and the existing Img
component will be the default value of that prop. This will give us our final CarouselSlide.js
for the chapter, which is provided at the end of the lesson.
CarouselSlide.propTypes = {
Img: PropTypes.elementType, // 1
imgHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
imgUrl: PropTypes.string.isRequired,
description: PropTypes.node.isRequired,
attribution: PropTypes.node,
};
PropTypes.elementType
, newly added inprop-types@15.7.0
, validates that the prop is a valid argument toReact.createElement
: either the name of a DOM element (such as"div"
), or a component.
Exposing the Img
component provides a direct solution to the failing type()
test:
Get hands-on with 1400+ tech skills courses.