我有一个使用RTK查询钩子生成的简单的家庭列表,其中项目可以标记为收藏,并根据标记无效自动重新获取数据。当我在测试中运行项目时,一切都工作,msw无法匹配突变成功后第二次调用的相同GET请求,通过标签无效触发它。
服务:
export const homesApi = createApi({
reducerPath: 'homesApi',
baseQuery: fetchBaseQuery({
baseUrl: API_URL,
prepareHeaders: (headers, { getState }) => {
headers.set('Accept', `application/json`);
return headers;
},
}),
tagTypes: [
'Homes',
],
endpoints: (builder) => ({
getHomes: builder.query({
query: (params) => {
const url = qs.stringifyUrl(
{ url: '/homes', query: params },
{ skipEmptyString: true, skipNull: true }
);
return url
},
providesTags: (result) =>
result?.data
? [
...result.data.map(({ id }) => ({ type: 'Homes', id })),
{ type: 'Homes', id: 'LIST' },
]
: [{ type: 'Homes', id: 'LIST' }],
}),
homeFavorite: builder.mutation({
query(payload) {
const {id} = payload;
const url = `/homes/${id}/favorite`;
return {
url,
method: 'POST'
};
},
invalidatesTags: () => [{ type: 'Homes', id: 'LIST' }],
}),
}),
});
export const {
useGetHomesQuery,
useHomeFavoriteMutation
} = homesApi;
测试:
const store = configureStore({
reducer: {
[homesApi.reducerPath]: homesApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
immutableCheck: false,
}).concat(
homesApi.middleware
),
});
setupListeners(store.dispatch);
let cleanupListeners;
describe('Homes component', () => {
beforeEach(() => {
cleanupListeners = setupListeners(store.dispatch)
})
afterEach(() => {
cleanupListeners();
store.dispatch(homesApi.util.resetApiState())
});
it('should mark item favorite', async() => {
server.use(
rest.get(`${API_URL}/homes`, (req, res, ctx) => {
return res(
ctx.json(MOCK_SUCCESS)
);
}),
rest.post(`${API_URL}/homes/1/favorite`, (req, res, ctx) => {
return res(
ctx.json({})
);
}),
);
render(
<Provider store={store}>
<BrowserRouter>
<Routes>
<Route path={'/'} element={<Homes/>}/>
</Routes>
</BrowserRouter>
</Provider>
);
const user = userEvent.setup();
const items = await screen.findAllByTestId('homeItem');
expect(items.length).toBe(5);
const icon = within(items[0]).getByTestId('fIcon');
expect(icon).not.toHaveClass('fav');
await user.click(icon);
//here I try to match the request for the second time with new data
server.use(
rest.get(`${API_URL}/homes`, (req, res, ctx) => {
return res(
ctx.json(MOCK_SUCCESS_UPDATED)
);
}),
)
const itemsNew = await screen.findAllByTestId('homeItem');
expect(within(itemsNew[0]).getByTestId('fIcon')).toHaveClass('fav');
})
});
不知道我做错了什么,因为我无法匹配相同的GET请求第二次不管我怎么尝试。下面是我得到的错误
[MSW]警告:捕获的请求没有匹配的请求处理程序:
try out with
https://mswjs.io/docs/api/response/once
对一个API调用进行一次模拟响应的基本思想
如果你两次调用同一个端点,它将只响应一次
这是我的用例,我获取数据,然后运行post请求来添加数据,然后我需要重新获取数据,以便更新的数据出现在UI中,
尝试不使用全局处理程序,并在测试中执行:
server.use(
rest.get('your/endpoint', (req, res, ctx) =>
res.**once**(ctx.json(replaceDataHereWithDesiredResponse))
)
)
两次,当然,以上代码都在同一个测试子句
中