제공자에 대한 옵션을 사용하여 테스트 라이브러리 사용자 정의 렌더링에 반응하십시오.
33388 단어 rtljavascripttestingreact
이와 유사한 방식으로:
renderUi(<Component />, {
withReduxProvider: true,
withReactQueryProvider: true,
})
이 예제에서는 애플리케이션에서 사용하지 않을 수 있는 일부 공급자를 사용하고 여기서는 사용하지 않는 다른 공급자를 사용할 수도 있습니다. 이 동일한 패턴에 따라 코드를 추가하기만 하면 됩니다. 버전도 마찬가지입니다. 이 라이브러리가 구현을 변경하는 방식에 따라 이 코드가 변경될 수 있습니다.
계속합시다.
먼저 이를 가능하게 할 도우미 파일을 만듭니다.
구현
// this file simplifies the component setup process when rendering the component for testing
import React from 'react';
import { render, RenderOptions } from '@testing-library/react';
import { Provider } from 'react-redux';
import { MemoryRouter as Router } from 'react-router-dom';
import { QueryClientProvider } from 'react-query';
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';
import axios from 'axios';
import store from '/services/rootReducer';
import { createTestQueryClient } from '/services/test/utils';
interface IExtendedRenderOptions extends RenderOptions {
withRouter?: boolean
routerHistory?: string[]
withRedux?: boolean
mockInitialState?: any
withQueryProvider?: boolean
mockAxiosCalls?: any
}
// wrappers and contexts
const wrapInRedux = (componentTree: JSX.Element, { mockInitialState }: IExtendedRenderOptions) => {
const storeConfig = configureStore([thunk]);
const storeMock = mockInitialState ? storeConfig(mockInitialState) : store;
// This allows you to use a passed mock store
return (
<Provider store={storeMock}>
{componentTree}
</Provider>
);
};
const wrapInRouter = (componentTree: JSX.Element, routerHistory?: string[]) => (
<Router initialEntries={routerHistory}>
{componentTree}
</Router>
);
const wrapInQueryProvider = (componentTree: JSX.Element) => {
const testQueryClient = createTestQueryClient();
return (
<QueryClientProvider client={testQueryClient}>
{componentTree}
</QueryClientProvider>
);
};
// You don't need this option if you are using something more advance such as Mock Service Worker
// This Function Mock axios calls and hand back a response for each call finding the right response by comparing the called endpoint with the endpoint fragment you passed
// You need to pass an array of objects, each object will represent a call
// { endpointFragment: string, expectedMockResponse: yourMockType }
type AxiosCallMock = { endpointFragment: string, expectedMockResponse: any }
// This one will runs on each axios get request
const mockAxiosCallResponsesIfAny = (renderOptions?: IExtendedRenderOptions) => {
if (renderOptions?.mockAxiosCalls) {
axios.get.mockImplementation((url) => {
// If your component has multiple axios calls make sure to pass
// endpoint fragments that identify them
const optionObject = renderOptions?.mockAxiosCalls.find((mock: AxiosCallMock) => url.includes(mock.endpointFragment));
return Promise.resolve(optionObject.expectedMockResponse);
});
}
};
const setupComponent = (ui: JSX.Element, renderOptions?: IExtendedRenderOptions) => {
if (!renderOptions) return ui;
let componentTree = <>{ui}</>;
if (renderOptions.withRouter) componentTree = wrapInRouter(componentTree, renderOptions.routerHistory);
if (renderOptions.withRedux) componentTree = wrapInRedux(componentTree, renderOptions);
if (renderOptions.withQueryProvider) componentTree = wrapInQueryProvider(componentTree);
return componentTree;
};
const customRender = (ui: JSX.Element, renderOptions?: IExtendedRenderOptions) => {
try {
mockAxiosCallResponsesIfAny(renderOptions);
const componentTree = setupComponent(ui, renderOptions);
return render(componentTree);
} catch (error) {
console.log(error);
throw error;
}
};
export * from '@testing-library/react';
export { customRender, IExtendedRenderOptions };
용법
테스트에서 구성 요소를 렌더링하는 방법입니다.
// Component.test.tsx
import React from 'react';
// we import out customRender
import { customRender, screen, fireEvent, waitFor } from 'ns_libs/testing/testUtils';
import Component from 'pages';
const initialProps: IProps = {
toggle: () => {},
isOpen: true,
target: 'test-popover-target',
feature: FEATURES_LIST.PORTFOLIO_GROUPS,
subprojectId: 0,
};
// initialize redux state with any value you want
// maybe same values that is initialized in your app
const initialReduxState = {
user: {
name: "",
age: 0,
}
}
const renderUi = (props: IProps = initialProps) => customRender(
<Component {...props} />, {
withRouter: true,
routerHistory: [':some_path_maybe'],
withRedux: true,
mockInitialState: initialReduxState,
},
);
구성 요소에서 발생하는 모의 축 호출에 해당 옵션을 계속 사용해야 하는 경우 모의 축 호출에 모의 데이터를 전달하는 예입니다.
import React from 'react';
import { customRender, screen, act, waitFor } from 'ns_libs/testing/testUtils';
import '@testing-library/jest-dom';
import axios from 'axios';
// Sample Component
const SampleComponent = () => {
const [data, setData] = React.useState<any>();
const [dataTwo, setDataTwo] = React.useState<any>();
const getTodos = async (): Promise<any> => {
try {
const res = await axios.get('https://yourendpoint.todos.com');
setData(res);
} catch (error) {
console.log(error);
}
};
const getOtherThings = async (): Promise<any> => {
try {
const res = await axios.get('https://endpoint.otherthings.com');
setDataTwo(res);
} catch (error) {
console.log(error);
}
};
React.useEffect(() => {
getTodos();
getOtherThings();
}, []);
return (
<div>
{data && <h1>{data?.map((item: any) => <span key={item.email}>{item.title}</span>)}</h1>}
{dataTwo && <h1>{dataTwo?.map((item: any) => <span key={item.email}>{item.title}</span>)}</h1>}
</div>
);
};
export default SampleComponent;
// Here starts the test for Sample Component
const ResponseMock: any = [
{
endpointFragment: '/todos',
expectedMockResponse: [
{
title: 'Nice First Title',
description: 'The todo is this',
},
title: 'Nice Second Title',
description: 'The todo is this',
{
},
],
},
{
endpointFragment: '/otherthings',
expectedMockResponse: [
{
title: 'First Other',
content: 0,
},
{
title: 'Second Other',
content: 0,
},
],
},
];
const renderUi = () => customRender(<SampleComponent />, {
mockAxiosCalls: ResponseMock,
});
describe('Test Component', () => {
afterEach(() => {
jest.resetAllMocks();
});
test('First test', async () => {
renderUi();
await waitFor(() => {
const title = screen.getByText('Nice First Title');
const title2 = screen.getByText('Nice Second Title');
const title3 = screen.getByText('First Other');
const title4 = screen.getByText('Second Other');
expect(title).toBeInTheDocument();
expect(title2).toBeInTheDocument();
expect(title3).toBeInTheDocument();
expect(title4).toBeInTheDocument();
});
});
});
Reference
이 문제에 관하여(제공자에 대한 옵션을 사용하여 테스트 라이브러리 사용자 정의 렌더링에 반응하십시오.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/niubo/react-testing-library-custom-render-with-options-for-providers-222o텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)