首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何利用useReducer的调度功能测试get请求后的状态更新?

如何利用useReducer的调度功能测试get请求后的状态更新?
EN

Stack Overflow用户
提问于 2022-10-02 16:25:12
回答 1查看 108关注 0票数 0

我试图理解如何编写单元测试的逻辑。但我被困在这里了。我有一个简单的产品列表页面,它根据过滤选项发送请求,并返回相关产品。getProducts函数提取相关产品并更新我的全局状态。我怎么测试这个?逻辑应该是什么?

getProducts函数

代码语言:javascript
运行
复制
  const getProducts = async () => {
    const { color, brand, sort, search, page } = state;
    const URL = `/api/v1/products?page=${page}&color=${color}&brand=${brand}&sort=${sort}&search=${search}`;
    dispatch({ type: SETUP_PRODUCTS_BEGIN });
    try {
      const { data } = await axios(URL);
      dispatch({
        type: SETUP_PRODUCTS_SUCCESS,
        payload: {
          products: data.products,
          colorOptions: data.colorOptions,
          brandOptions: data.brandOptions,
          numOfPages: data.numOfPages,
        },
      });
    } catch (error) {
      console.log(error);
    }
  };

减速器

代码语言:javascript
运行
复制
if (action.type === SETUP_PRODUCTS_BEGIN) {
    return { ...state, isLoading: true };
}
if (action.type === SETUP_PRODUCTS_SUCCESS) {
  return {
    ...state,
    isLoading: false,
    products: action.payload.products,
    colorOptions: action.payload.colorOptions,
    brandOptions: action.payload.brandOptions,
    numOfPages: action.payload.numOfPages,
  };
}

initialState

代码语言:javascript
运行
复制
const initialState = {
  products: [],
  isLoading: false,
  colorOptions: null,
  brandOptions: null,
  numOfPages: null,
};
EN

Stack Overflow用户

发布于 2022-10-02 17:24:46

你的问题太笼统了。

你在问题中提到了两个组成部分:

  1. 产品清单反应元件
  2. 带减速器的剩馀状态

为了对单元测试组件进行单元测试,需要能够控制所有外部依赖项。您的所有代码组件/模块只应承担一项责任。

让我们分析一下您拥有的内容:您的UI组件有太多的知识--它知道如何从后端获取数据,甚至知道API的路径。您的组件必须知道如何基于props/redux状态进行呈现,以及在某些事件上调度哪些操作。

不幸的是,如果您使用useDispathc和useElector redux钩子,这意味着您必须测试组件和redux状态。

这是我的推荐。(示例使用jest)

  1. 你需要对减速器进行单元测试。因为它们是纯javascript函数,所以我们不需要模拟任何东西。
代码语言:javascript
运行
复制
import reducer from "/path-to-the-reducer";

describe("Action SETUP_PRODUCTS_BEGIN", () => {
  it("Should set isLoading to true nomatter what", () => {
    //setup
    const initialState = { abc: "Germany", isLoading: undefined };

    //act
    cons resultState = reducer(initialState, { type: SETUP_PRODUCTS_BEGIN });

    //assert
    expect(resultState.isLoading).toBe(true);
  });
})
  1. 为了测试组件,需要做两件事:

2.1将rest调用分离到一个单独的模块中。在这种情况下,您将允许其他UI组件在API调用中重用相同的逻辑。这是一个非常基本的例子:

RestApi.js

代码语言:javascript
运行
复制
const listProducts = async (input) => {
  const { color, brand, sort, search, page } = input;
  const URL = `/api/v1/products?page=${page}&color=${color}&brand=${brand}&sort=${sort}&search=${search}`;
  const axiosResult = await axios(URL);
  return axios.data;
}

2.2你需要使用一个库来测试你的反应组件。在撰写本文时,react建议使用React测试库 反应试验

所以你需要做几件事:

  • 模拟您需要的RestApi方法
  • 模拟redux状态并“侦听调度”
  • 确保组件基于支持/还原状态呈现正确的内容

我将发布一些伪javascript代码来说明它的外观。

代码语言:javascript
运行
复制
import { listProducts } from './restAPI'

//mockign the listProducts to return empty array each time
jest.mock('./restAPI', () => ({
  listProducts : () => Promise.resolve([]),
}))


describe("Component initialization ", async () => {
  it("Should call SETUP_PRODUCTS_BEGIN and SETUP_PRODUCTS_SUCCESS on componend load", () => {
    /// configureStore from the @reduxjs/toolkit npm package
    const store = configureStore({ reducer: {}, { isLoading: true, products: [] } })
    const renderResult = await render(<Provider store={store}><ProductListComponent /></Provider>);

   //assert
   const actions = store.getActions();

   expect(actions).toHaveLength(2);
   expect(actions[0].type).toEqual("SETUP_PRODUCTS_BEGIN");
   expect(actions[1].type).toEqual("SETUP_PRODUCTS_SUCCESS");
  });
});

单元测试中的剩余

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73927491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档