使用 MSW 测试 React-query,并将数据传递给子组件
Posted
技术标签:
【中文标题】使用 MSW 测试 React-query,并将数据传递给子组件【英文标题】:Testing React-query with MSW with the data passed to a child component 【发布时间】:2021-12-14 03:18:18 【问题描述】:我正在使用 React-query 并尝试对其进行测试,在父组件中调用数据并传递给子组件以呈现项目列表。我已经设置了 MSW,但是当我尝试我的测试时:
const queryClient = new QueryClient()
it('Should give a response', async () =>
render(<QueryClientProvider client=queryClient><Component /></QueryClientProvider>);
expect(await screen.findByTestId('test-data')).toBeInTheDocument();
)
我明白了:
Unable to find an element by: [data-testid="test-data"]
<body>
<div>
<div
class="mt-5"
>
Loading data ...
</div>
</div>
</body>
父组件是这样的:
const Component1: React.FunctionComponent = () =>
const [fetchData, setFetchData] = React.useState<IData[]>([]);
const queryKey = 'mainData';
const getData = async (): Promise<any> =>
await new Promise(resolve => setTimeout(resolve, 1000))
const response = await axios.get(`xxxxxxx`).then(res => res.data);
return response;
const data: result, status, isRefetching, error, refetch : any = useQuery(queryKey, getData,
refetchOnWindowFocus: true,
staleTime: 0,
cacheTime: 0,
refetchInterval: 0,
);
return (
<>
status === 'error' && (
<div className="mt-5">error.message</div>
)
status === 'loading' && (
<div className="mt-5">Loading data ...</div>
)
status === 'success' && (
<div className="row dashboard">
<ChildComponent data=fetchData data-testid="test-data"/> // data passed to this component
<br />
</div>
)
isRefetching ? 'Updating...' : null
</>
)
;
export default Component1;
设置测试:
import '@testing-library/jest-dom';
import server from './mocks/server'
// Establish API mocking before all tests.
beforeAll(() => server.listen())
// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => server.resetHandlers())
// Clean up after the tests are finished.
afterAll(() => server.close())
处理程序
import rest from 'msw';
export const handlers = [
rest.get('https://xxxxxxxx', (req, res, ctx) =>
return res(
ctx.json([
"titleNumber": 499,
"model": "Yes Model",
,
"titleNumber": 434,
"model": "No Model",
,
])
);
),
];
服务器
import setupServer from 'msw/node'
import handlers from './handlers'
export const server = setupServer(...handlers)
我是不是在错误的地方进行测试?
【问题讨论】:
您确定 MSW 工作正常吗? 是的,但那不是测试 api 调用本身是否正在返回一些东西。你需要测试看看 getData() 是否真的从 msw 返回了一些东西。您可以发布指向 github 存储库或其他内容的链接吗? 我觉得有些东西不见了,你能发个github链接什么的吗?会更容易解决 这正在讨论中,但您应该能够使用旨在捕获 api 调用的 msw 来做到这一点,因此它不应该进入身份验证。这意味着 msw 可能无法正常工作 这是一个非常奇怪的问题。刚刚更新了我的答案 【参考方案1】:更新答案
好的,这是一个非常奇怪的问题。我复制了它并得到了同样的东西,即使它不应该。我认为问题可能与反应查询和测试有关,而不是与 msw 有关。为了解决它,我只是开玩笑地告诉useFakeTimers
,然后它就起作用了
describe('should return data', () =>
beforeEach(() =>
jest.useFakeTimers();
);
it('Should give a response', async () =>
render(
<QueryClientProvider client=queryClient>
<App />
</QueryClientProvider>
);
expect(await screen.findByTestId('test-data')).toBeInTheDocument();
// screen.debug();
);
);
我认为问题在于您将 data-testid="test-data"
作为道具传递到 ChildComponent
并且我猜您没有在组件内部使用它,这意味着它实际上并没有附加到任何DOM 元素。这可以解释为什么它说它找不到元素,因为除非你在 ChildComponent
内部使用它,否则它不会被使用。
尝试将其添加到作为 don 节点而不是组件的元素中,例如它所在的 div。
status === 'success' && (
<div className="row dashboard" data-testid="test-data">
<ChildComponent data=fetchData />
<br />
</div>
)
【讨论】:
Unable to find an element by: [data-testid="test-data"].. 我想知道我是否将其余的 mock 移到了测试文件本身中。 加载部分没有通过 确实有效,那么'jest.useFakeTimers();
到底是什么没有遇到过呢?
useFakeTimers 只是告诉任何会使用时间(即 setTimeout、setInterval)来伪造它的东西。而不是使用实际的东西。因此,在您的情况下,您使用的是 setTimeout 而不是使用它来伪造它。以上是关于使用 MSW 测试 React-query,并将数据传递给子组件的主要内容,如果未能解决你的问题,请参考以下文章
使用 MSW 和 Jest 时如何在请求之间的测试中清除 RTK 查询缓存?
Jest 使用 Mock Service Worker (MSW) 或其他模拟离线网络?