在收到请求后,如何使用useReducer的调度功能测试状态更新



我正在努力理解如何编写单元测试的逻辑。但我被困在这里了。我有一个简单的产品列表页面,它根据筛选选项发送请求并返回相关产品。getProducts功能拉取相关产品并更新我的全局状态。我该如何测试?逻辑应该如何?

getProducts函数
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);
}
};
减速器
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
const initialState = {
products: [],
isLoading: false,
colorOptions: null,
brandOptions: null,
numOfPages: null,
};

你的问题太笼统了。

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

  1. 产品列表React Component
  2. 具有某些减速器的一种减速状态

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

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

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

这是我的建议。(示例使用jest(

  1. 您需要对减速器进行单元测试。由于它们是纯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 api调用分离到一个单独的模块中。在这种情况下,您将允许其他UI组件为API调用重用相同的逻辑。这是一个非常基本的例子:

RestApi.js

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推荐react测试库react测试。

所以你需要做一些事情:

  • 模拟您需要的RestApi方法
  • 模拟冗余状态;监听急件">
  • 确保您的组件基于props/reduxState呈现正确的内容

我将发布一些伪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");
});
});

Redux单元内测试

相关内容

最新更新