react-testing-library: Child Component Props Not Rendered Into Snapshot
@testing-library/reactversion:@testing-library/react@11.1.0- Testing Framework and version:
- DOM Environment:
jest@23.6.0,node@10.19.0,react@16.11.0,react-dom@16.13.0
Relevant code or config:
The main component to be tested:
// 3rd party libs
import React from 'react';
// components
import LinkItemsAutocomplete from 'common-react/link-items-autocomplete/link-items-autocomplete';
// types
import type { AssetPdpModel } from '../../asset-curation.types';
interface PdpTabDataProps {
data: AssetPdpModel;
disabled: boolean;
onSearchQueryChange: (query: string) => void;
onAddItem: (nodeId: string) => void;
onRemoveItem: (nodeId: string) => void;
}
export default function PdpTabData({
data,
disabled,
onSearchQueryChange,
onAddItem,
onRemoveItem,
}: PdpTabDataProps): React.ReactElement {
const baseClassName = 'pdp-tab-data';
return (
<div className={baseClassName}>
<LinkItemsAutocomplete
data-testid="LinkItemsAutocomplete"
id="pdp-linked-groups"
title="asset.linked.group.header"
subText="asset.linked.group.subtext"
items={data.linkedGroups.linkedItems}
suggestions={data.linkedGroups.search.suggestions}
maxItemsCount={1}
disabled={disabled}
onSearchQueryChange={onSearchQueryChange}
onAddItem={onAddItem}
onRemoveItem={onRemoveItem}
/>
</div>
);
}
The test:
import React from 'react';
import { render, cleanup } from '@testing-library/react';
import PdpTabData from './pdp-tab-data';
jest.mock('common-react/link-items-autocomplete/link-items-autocomplete');
describe('PdpTabData', () => {
let component;
let props;
const defaultProps = {
data: {
linkedGroups: {
linkedItems: 'linkedItems',
search: {
suggestions: 'suggestions',
},
},
},
disabled: false,
onSearchQueryChange: jest.fn(),
onAddItem: jest.fn(),
onRemoveItem: jest.fn(),
};
const getDefaultProps = () => defaultProps;
const setup = () => {
props = getDefaultProps();
component = render(<PdpTabData {...props} />);
};
beforeEach(() => {
setup();
});
afterEach(() => {
cleanup();
});
afterEach(() => {
jest.clearAllMocks();
});
describe('Renderings', () => {
it('should render the component against default mockdata', () => {
expect(component.asFragment()).toMatchSnapshot();
});
});
});
The rendered snapshot:
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PdpTabData Renderings should render the component against default mockdata 1`] = `
<DocumentFragment>
<div
class="pdp-tab-data"
>
<linkitemsautocompletemock
data-testid="LinkItemsAutocomplete"
id="pdp-linked-groups"
items="linkedItems"
maxitemscount="1"
subtext="asset.linked.group.subtext"
suggestions="suggestions"
title="asset.linked.group.header"
/>
</div>
</DocumentFragment>
`;
What you did:
What happened:
Writing a simple first test using @testing-library/react, with the expectation that all component props for rendered child component (including function callback props?) to be rendered out into the snapshot.
Reproduction:
Problem description:
I observed three things:
-
The
disabledprop was not rendered out at all in the snapshot when it’s set tofalse. I’m guessing this is Intended since the snapshot is mounted off a DOM element? And so falsy attribute boolean values are generally omitted. -
Also when the
disabledprop is set to true, it renders out the prop, but with an empty value;disabled="". Should this rather be rendered out asdisabled(note without equality symbol + empty string quotes)? -
Callback function props (
onSearchQueryChange,onAddItem,onRemoveItem) are also not rendered out into the snapshot. I’m guessing this is also intended, due to the DOM mounting?
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 17 (8 by maintainers)
Perfect! Thanks a lot for the taking the time to explain and linking to the article — Will definitely read it through.
Your explanation makes sense as, in fact, this is the way the browser works when printing an element:
So I guess we should expect the same behaviour here, and when in ultimate need to keep track of those handlers in snapshots, we could always use
react-test-rendererin order to keep original React output.But overall, I will try to reconsider my approach and check if simply having a test case checking for a callback isn’t a better solution as opposed to having those handles included in a snapshot. (It probably is 😜 )
@zanona Well, since
testing-libraryworks directly with DOM nodes, the actual callbacks for the events aren’t being added since they are handled by event handlers through javascript (that’s the React way). I do think that the approach of snapshot testing is problematic and should be used sparingly. You can see an explanation here: http://kcd.im/snapshotsOk, if you still think there’s an issue with the library related to custom events, please open a new issue (as this was originally about things supposedly not in the snapshot). It’d be nice if before doing so you really make sure this is potentially a bug or shortcoming of the library. Maybe asking around in a forum such as those I mentioned. Or if you’re already convinced open the issue. When doing so, having a minimal runnable example such as a small codesandbox goes a long way in having me or others here be better able to help you. Out-of-context dumps of the code in the app you’re working are more difficult to comprehend as they usually have a low signal to noise ratio.