So..I am trying to use stories for my unit test with jest RTL to minimize duplication (explained here) and the test throws "Types of property 'id' are incompatible" error when I pass the args that is also used in my story.
I am currently using below packages as my testing suite.
"@storybook/react": "^6.5.9",
"@storybook/testing-react": "^1.2.4",
"@testing-library/react": "^13.3.0",
"jest": "^28.1.1",
// and others...
Below is my test.
import * as React from 'react';
import { screen, render } from '@testing-library/react';
import { Default as Checkbox } from '../../stories/AccountCheckbox.stories';
const renderCheckbox = () => {
render(<Checkbox {...Checkbox.args} />); // the point where it throws an type error that says 'id is incompatible'.
}
describe('<AccountCheckbox />', () => {
test('should display account information', () => {
renderCheckbox();
expect(screen.getByTestId('example-test-id')).toBeInTheDocument();
});
});
Below is my story.
import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import AccountCheckbox from '../components/AccountCheckbox';
import { StoryAppWrapper } from '../../.storybook/wrapper/StoryAppWrapper';
export default {
title: 'AccountCheckbox',
component: AccountCheckbox,
decorators: [(Story) => <StoryAppWrapper>{Story()}</StoryAppWrapper>]
} as ComponentMeta<typeof AccountCheckbox>;
const Template: ComponentStory<typeof AccountCheckbox> = (args) => (
<AccountCheckbox {...args} />
);
export const Default = Template.bind({});
// These are the args I am trying to utilize in my test as well.
Default.args = {
id: 'example-id',
testId: 'example-test-id',
label: 'Account 1',
selected: false,
onChange: () => { },
};
Below is the type for the checkbox I declared.
export type CheckboxProps = {
id: string;
testId: string;
label: string;
selected: boolean;
onChange: any;
};
Below is the actual code.
import * as React from 'react';
import { Checkbox } from 'custom-lib';
import { CheckboxProps } from '../../types/types';
const AccountCheckbox = ({
id,
testId,
label,
selected,
onChange,
}: CheckboxProps): JSX.Element => {
return (
<Checkbox
id={id}
data-testid={testId}
label={label}
state={selected ? 'true' : 'false'}
onChange={onChange}
/>
);
};
export default AccountCheckbox;
Can anyone pinpoint what I've missed within these codes?
CodePudding user response:
You're trying to render the Story, not the Checkbox itself. Why not import the checkbox directly, but use the story args too?
import * as React from 'react';
import { screen, render } from '@testing-library/react';
import AccountCheckbox from '../components/AccountCheckbox';
import { Default as AccountCheckboxStory } from '../../stories/AccountCheckbox.stories';
const renderCheckbox = () => {
render(<AccountCheckbox {...AccountCheckboxStory.args} />);
}
describe('<AccountCheckbox />', () => {
test('should display account information', () => {
renderCheckbox();
expect(screen.getByTestId('example-test-id')).toBeInTheDocument();
});
});
You may need to adjust paths to the Story/AccountCheckbox as I'm not quite sure what your directory structure looks like.
Update
Going from your comment and the link, it seems that they are using some form of a compositional function to wrap the exported stories and return them as components. So in your case, would you not do this:
import React from 'react';
import { render, screen } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import * as stories from '../../stories/AccountCheckbox.stories';
const { Default: AccountCheckBoxDefault } = composeStories(stories);
test('renders profile page', async () => {
render(<AccountCheckBoxDefault />);
// ... some assertions here
});
describe('<AccountCheckbox />', () => {
test('should display account information', () => {
renderCheckbox();
expect(screen.getByTestId('example-test-id')).toBeInTheDocument();
});
});
I don't think it's actually necessary to pass in the args, as those args should be used by the story itself.