I have a parent component called DismissButton
:
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { StyledDismissButton } from './Styled';
import { IoClose } from 'react-icons/io5';
import VisibilityContext from '../../context';
export const DismissButton = () => {
const { setVisible } = useContext(VisibilityContext);
const hideToast = () => setVisible(false);
return (
<StyledDismissButton aria-label="Close" onClick={hideToast}>
<IoClose />
</StyledDismissButton>
);
};
StyledDismissButton.propTypes = {
onClick: PropTypes.func.isRequired,
};
export { StyledDismissButton };
It consumes this context
:
import { createContext } from 'react';
const initialState = {
visible: true,
setVisible: () => {},
};
const VisibilityContext = createContext(initialState);
export default VisibilityContext;
It holds a child component StyledDissmissButton
:
import styled from "styled-components";
const StyledDismissButton = styled.span`
right: 0;
cursor: pointer;
`;
export { StyledDismissButton };
I want to test DismissButton
with Enzyme and Jest but I failed each time because the component consumes a context. I've tried this soltion but it does not work for me.
Test
import 'jsdom-global/register';
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import DismissButton, { StyledDismissButton } from './index';
import { IoClose } from 'react-icons/io';
Enzyme.configure({ adapter: new Adapter() });
it('renders one <StyledDissmisButton> when passed in', () => {
const contextValue = {
visible: true,
setVisible: () => {},
hideToast() {
this.setVisible(false);
},
};
const element = shallow(<DismissButton />);
expect(
element.contains(
<StyledDismissButton aria-label="Close" onClick={contextValue.hideToast}>
<IoClose />
</StyledDismissButton>
)
).toEqual(true);
});
Test Result
expect(received).toEqual(expected)
Expected value to equal:
true
Received:
false
at Object.<anonymous> (src/components/Toast/Header/DismissButton/index.test.js:32:7)
at new Promise (<anonymous>)
at node_modules/p-map/index.js:46:16
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 4 passed, 5 total
Snapshots: 1 passed, 1 total
Time: 13.773s
You can check the repos on React Toast
Debugging result
<TestComponent>
<Component>
<styled.span aria-label="Close" onClick={[Function: hideToast]}>
<span aria-label="Close" onClick={[Function: hideToast]} className="sc-bdnxRM gsGVlo">
<IoClose>
<IconBase attr={{...}}>
<svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" className={[undefined]} style={{...}} height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">
<path d="M289.94 256l95-95A24 24 0 00351 127l-95 95-95-95a24 24 0 00-34 34l95 95-95 95a24 24 0 1034 34l95-95 95 95a24 24 0 0034-34z" />
</svg>
</IconBase>
</IoClose>
</span>
</styled.span>
</Component>
</TestComponent>
Update
After a deep focusing I've found that Styled Component generates add a class to the component which makes the matching impossible:
<span aria-label="Close" onClick={[Function: hideToast]} className="sc-bdnxRM gsGVlo">
But I don't know how to pass that class in the test?