【问题标题】:msw not able to match the same request the second time with updated data in a single testmsw 无法在一次测试中第二次将相同的请求与更新的数据匹配
【发布时间】:2022-11-24 01:38:35
【问题描述】:

我有一个使用 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] 警告:捕获了没有匹配请求处理程序的请求:

【问题讨论】:

  • 你找到解决办法了吗?

标签: reactjs jestjs react-testing-library rtk-query msw


【解决方案1】:

试试

https://mswjs.io/docs/api/response/once

res.once 对 1 个 api 调用的模拟响应的基本思想

如果您两次调用同一个端点,它只会响应一次

这是我的用例,我获取数据,然后运行发布请求以添加数据,然后我需要重新获取数据以便更新后的数据出现在 UI 中,

尝试不使用全局处理程序,并在您的测试中执行以下操作:

server.use(rest.get('你的/端点', (req, res, ctx) => res.一次(ctx.json(replaceDataHereWithDesiredResponse)))

两次,当然,上面的代码在同一个测试条款中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2015-10-05
    • 1970-01-01
    相关资源
    最近更新 更多