Skip to content

Commit 9b53a2f

Browse files
authored
feat: Mocked elements can now be configured with a custom element
resolves #5
2 parents 59dc5c9 + a4ff96b commit 9b53a2f

File tree

3 files changed

+44
-11
lines changed

3 files changed

+44
-11
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,10 @@ This library compliments `@testing-library/react` to make it easy to setup and m
4545
expect(getMockComponent(MyChildComponent).props.open).toBe(true);
4646
```
4747

48-
*Note:* this way of testing ensures that the component is **currently** rendered with the provided value. Jest's `toHaveBeenCalledWith` would only test that was ever rendered with the expected value.
48+
*Note:* this way of testing ensures that the component is **currently** rendered with the provided value. Jest's `toHaveBeenCalledWith` would only test that was ever rendered with the expected value.
49+
50+
### Customization
51+
52+
`setupMockComponent` takes an options argument that can change the behavior of the mock.
53+
54+
To change the element used from a div, pass the element name. This is useful when the mock is used in a place where only certain elements are valid (ex. a child of a `tbody` must be a `tr`)

src/customizations.spec.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { render } from '@testing-library/react';
2+
import React from 'react';
3+
import { setupMockComponent, getByMockComponent } from './index';
4+
import MockedComponent from './test-components/MockedComponent';
5+
6+
jest.mock('./test-components/MockedComponent');
7+
8+
it('should use a custom element', () => {
9+
setupMockComponent(MockedComponent, {element: 'tr'});
10+
11+
render(<table><tbody><MockedComponent /></tbody></table>);
12+
13+
expect(getByMockComponent(MockedComponent).tagName).toEqual('TR');
14+
});

src/setupMockComponent.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { RefCallback, useEffect, useRef } from "react";
1+
import React, { ReactHTML, RefCallback, useEffect, useRef } from "react";
22
import { FC } from "react";
33

44
export type MockedComponent<PropType> = jest.MockedFunction<FC<PropType>>;
@@ -16,25 +16,38 @@ function ensureIsMock<PropType>(mockedComponent: FC<PropType>) {
1616
}
1717
}
1818

19-
export function setupMockComponent<PropType>(mockedComponent: FC<PropType>) {
20-
ensureIsMock(mockedComponent);
19+
export interface MockComponentOptions {
20+
/**
21+
* The react element generated by the mock. `div` by default.
22+
*/
23+
element?: keyof ReactHTML;
24+
}
2125

22-
const comp = mockedComponent as MockedComponent<PropType>;
23-
comp.mockImplementation((props: PropType) => {
26+
export function setupMockComponent<PropType>(mockedComponent: FC<PropType>, options?: MockComponentOptions) {
27+
ensureIsMock(mockedComponent);
28+
29+
const mockImplementation: FC<PropType> = (props) => {
2430
const mockedElmentRef = useRef<MockedElement<PropType> | null>(null);
2531
useEffect(() => {
2632
if (mockedElmentRef.current) {
2733
mockedElmentRef.current.props = props;
2834
}
2935
}, [props]);
30-
const refCallback: RefCallback<HTMLDivElement> = (el) => {
36+
37+
const ref: RefCallback<HTMLDivElement> = (el) => {
3138
mockedElmentRef.current = el as unknown as MockedElement<PropType>;
3239
if (mockedElmentRef.current) {
3340
mockedElmentRef.current.component = comp;
3441
}
3542
};
36-
return (
37-
<div ref={refCallback} data-testid={mockElementTestId} />
38-
);
39-
});
43+
44+
const type: keyof ReactHTML = options?.element ?? 'div';
45+
return React.createElement(type, {
46+
ref,
47+
'data-testid': mockElementTestId,
48+
});
49+
};
50+
51+
const comp = mockedComponent as MockedComponent<PropType>;
52+
comp.mockImplementation(mockImplementation);
4053
}

0 commit comments

Comments
 (0)