I have this component:
import React from 'react';
export const ThemeSwitch = ({ theme, themeToggler }) => {
return (
theme === 'light'
? <div onClick={themeToggler}><h2>dark</h2><img src="assets/icon-moon.svg" alt="icon of a moon" /></div>
: <div onClick={themeToggler}><h2>light</h2><img src="assets/icon-sun.svg" alt="icon of a sun" /></div>
);
};
I have this test suite:
describe("Theme Switch Test", () => {
it('[1] Matches the snapshot', () => {
const theme = "light";
const component = renderer.create(<ThemeSwitch theme={theme} themeToggler={() => { }} />);
expect(component.toJSON()).toMatchSnapshot();
});
it('[2] Renders - "dark" with moon icon - if theme is set to light', () => {
const theme = "light";
const component = renderer.create(<ThemeSwitch theme={theme} themeToggler={() => { }} />).root;
const h2 = component.findByType('h2').props.children;
const imgSource = component.findByType('img').props.src;
expect(h2).toEqual('dark');
expect(imgSource).toEqual('assets/icon-moon.svg');
});
it('[3] Renders - "light" with sun icon - if theme is set to dark', () => {
const theme = "dark";
const component = renderer.create(<ThemeSwitch theme={theme} themeToggler={() => { }} />).root;
const h2 = component.findByType('h2').props.children;
const imgSource = component.findByType('img').props.src;
expect(h2).toEqual('light');
expect(imgSource).toEqual('assets/icon-sun.svg');
});
it('[4] Changes theme on click from - "dark" with moon icon - to - "light" with sun icon - and back', () => {
let theme = "light";
const onClick = () => {
theme = "dark";
};
const component = renderer.create(<ThemeSwitch theme={theme} themeToggler={() => onClick()} />).root;
const wrapper = component.findByType('div');
act(() => wrapper.props.onClick());
let h2 = component.findByType('h2').props.children;
let imgSource = component.findByType('img').props.src;
expect(h2).toEqual('light');
expect(imgSource).toEqual('assets/icon-sun.svg');
});
});
The first 3 tests pass normally but the last one fails on expect(h2).toEqual('light');
I am confused why this happens as when testing manually I see the component behaving as expected so changing the text and icon after the onClick event.
The error was caused by not updating the component after the onClick.
it('[4] Changes theme on click from - "dark" with moon icon - to - "light" with sun icon', () => {
// Defining props
let theme = "light";
const onClick = () => {
theme = "dark";
};
// Creating the TestRendererInstance
const component = renderer.create(<ThemeSwitch theme={theme} themeToggler={() => onClick()} />);
// repeting test [1]
let h2Text = component.root.findByType('h2').props.children;
let imgSource = component.root.findByType('img').props.src;
expect(h2Text).toEqual('dark');
expect(imgSource).toEqual('assets/icon-moon.svg');
// Triggering the onClick event of the component
act(() => component.root.findByType('div').props.onClick());
// Updating the testRenderer tree
component.update(<ThemeSwitch />);
// Test if text inside of h2 and src inside of img changed
h2Text = component.root.findByType('h2').props.children;
imgSource = component.root.findByType('img').props.src;
expect(h2Text).toEqual('light');
expect(imgSource).toEqual('assets/icon-sun.svg');
});