当前位置: 首页 > news >正文

宁波网站建设专业定制抖音引流推广一个30元

宁波网站建设专业定制,抖音引流推广一个30元,网站带后台模板,苏宁易购网站建设的目的React 测试笔记 03 - 测试 Redux 中 Reducer 状态变化 这段时间都在重构代码,把本来奇奇怪怪(singleton)的实现改成用 redux 的实现,然后就突然想到……即然 redux 的改变不涉及到 UI 的改变,那么是不是说可以单独写 redux 的测试……&#…

React 测试笔记 03 - 测试 Redux 中 Reducer 状态变化

这段时间都在重构代码,把本来奇奇怪怪(singleton)的实现改成用 redux 的实现,然后就突然想到……即然 redux 的改变不涉及到 UI 的改变,那么是不是说可以单独写 redux 的测试……?

找了一下资料,发现比想象中的简单很多,所以就稍微记一下

要求简述

这里的案例主要就是通过用户权限,然后 map 对应的页面的读写(全套为增删改查)权限,基本逻辑是这样的:

  • 权限分为 read_only、full、A、B、C(A/B/C 为抽象的权限,基本上说对应一下用户可以获得不同分类的权限)

  • 每个权限对应着每个页面的读写操作

    如 full 代表着用户对所有页面都有读写操作,read_only 相反

    A/B/C 给予用户 页面 A/页面 B/页面 C 的读写权限

  • 用户可以有不同的权限

  • 更高的权限将会复写较低的权限

    理论上来说这是不可能发生的事情,不过假设用户同时有 read_only 和 full,那么 full 将会复写 read_only 的权限

    比较通常发生的是用户可能会有 A/B/C 这样的权限,但是其中对某些页面会有覆盖操作,如权限 B 给予 B 页面读写操作,权限 C 可能对 B 页面有改的权限,但是没有增删

  • 当前 redux 状态只负责授予权限,具体权限的处理则是在 路由/component 处进行处理

实现简述

具体的实现就是 dispatch event 实现,权限的 map 则是通过 {page: permission} 的方式进行存储,至于要求说是取最高权限,因此 permission 的实现方式采用数字,在 redux 中使用 Math.max() 的方式取最大值

需要注意的是,这里在实现的时候可能会出现 type casting 的异常,如 0 | 1 | 2 | 3 is not compatible with number 之类的,我的实现方式是用 Math.max() as (typeof T)[keyof typeof T] 的方式进行一个转型

当然,cv 太多的话还是建议抽一个函数取实现

这样的话通过 roles.filter(role => role in SOME_CONST) 中可以获取需要 map 的权限,再遍历数组更新权限即可

测试实现

首先我先 mock 了一下整个 app component:

jest.mock('../../App', () => ({}));

这一步是假设 app component 已经渲染完毕了,因为其他的 redux 对一些 util——有可能是异步的操作——有一些依赖的关系,然后目前 jest 没有找到这些 util,因此就会抛出找不到 util 的异常,所以这里先 mock 一下虚构的 app,让 jest 知道内部的 util 实现不重要,最终结果就是所有的组件已经正常渲染完毕

其主要原因也是我们的项目有一些 context wrapper 了:

// redux
<Provider store={store}>{/* async code,从 API 处获得权限,再传到 redux 中 */}{/* 如果不 mock,从这里就会报错 */}<AccessContext><OtherContext><App /></OtherContext></AccessContext>
</Provider>

之后的操作非常的简单,jest 已经默认 app 可以正确渲染,因此这里只需要出发 RTK 的状态变化,并且检查状态变化即可,如:

import {ISliceType,sliceReducer,exportedAction,
} from '../../store/slices/state/keycloak';jest.mock('../../App', () => ({}));// 这里可以实现一些状态用来方便 test,而不用手写一堆代码
const initialState: ISliceType = {}; // AKA readOnly
const fullAccess: ISliceType = {};
const aAccess: Partial<ISliceType> = {};
const bAccess: Partial<ISliceType> = {};const validationHelper = (grantedPerm: ISliceType,checkAccess: Partial<ISliceType>
): boolean => {// do some check// 也许可以遍历 checkAccess 的 key,保证 grantedPerm[key] >= checkAccess[key] 这种return true;
};describe('test user has readOnly access', () => {test('initial state is set to readOnly', () => {expect(sliceReducer(undefined, { type: undefined })).toEqual(initialState);});test('user only has readOnly access', () => {const payload = { role: ['readonly'] };expect(sliceReducer(initialState, exportedAction(payload))).toEqual(initialState);});test('user has multiple role', () => {const payload = { role: ['readonly', 'aAccess'] };const grantedPerm = sliceReducer(initialState,exportedAction(payload)).permission;expect(validationHelper(grantedPerm, initialState)).toBeTruthy();expect(validationHelper(grantedPerm, aAccess)).toBeTruthy();expect(validationHelper(grantedPerm, bAccess)).toBeFalsy();});
});

这里检查了三种状态:

  • undefined 相当于触发 Reducer 的初始化,因此返回初始状态

    因为初始状态直接声明了,所以可以直接用 toEqual 去测试

  • 测试只读状态

    这里假设返回的状态依旧比较简单,因此仍旧可以使用 toEqual 去和整个状态测试

  • 测试更复杂的状态

    这个就是用的第三个方法,主要是用 toBeTruthy()toBeFalsy() 测试

    假设说页面有十几二十个,然后有四五组权限,全都手写的话会引入更多的 human error,这个时候就可以考虑将一些常量抽出来

    比如说 a 权限对应的 {page: access} 可以单独抽出来做一个变量——这个部分是可以实现、测试公用的,然后再写一个 helper function——这里可以用于测试给予的权限是否大于等于变量中的权限,而没有赋值的权限是否小于等于当前权限,这个根据具体需求具体实现

    我这里的 helper 直接返回了 boolean,使用上面列举的两个方式去测试,不过实际上还可以搭配其他的 Modifiers 和 Matchers 去测试,不仅仅是用 truthy/falsy

    这个不是必须的,因为测试有些情况下就是会 cv 一些代码,而且一些复杂的情况下,仅返回 boolean 的 helper 也许不是这么的好用,那么最差情况下就是得一遍遍手写,然后通过 npm test 去运行测试结果

reference

  • Writing Tests

    这里只用了单元测试 reducer 的部分

  • Expect

    下面的 reference 列举了 Modifiers 和 Matchers

http://www.ritt.cn/news/787.html

相关文章:

  • 免费浏览网站的软件今天最新的新闻头条新闻
  • 网站需求分析与设计方案企业官网定制设计
  • 山东省建设工程信息网官网宿州百度seo排名软件
  • 中国互联网数据平台官网如何进行搜索引擎优化 简答案
  • 成都网站制作培训北京百度推广客服电话多少
  • 上海网站建设软件下载sem优化和seo的区别
  • 武汉市网站设计游戏推广员拉人犯法吗
  • 太原网站建设杰迅科技全渠道营销
  • 做新闻网站用香港阿里云服务器网页制作基础教程
  • 江北网站建设海外独立站
  • 杭州房产网官方网站爱链
  • 上海c网站建设自己怎么做网站
  • 学校开发网站公司参考消息今天新闻
  • 网站后台登录系统是怎么做的国外网站制作
  • 石狮网站建设费用如何成为百度广告代理商
  • 企业网站需要响应式南昌网站优化公司
  • 支付宝 收费 网站开发百度推广外包
  • 网站设计的国际专业流程包括吉林百度seo公司
  • wordpress qq微信登录百度seo学院
  • 要建设网站seo工具不包括
  • 松原企业网站建设小说推广接单平台
  • 怎么判断一个网站是否使用帝国做的网络营销的推广方法
  • wordpress瀑布流分页seo公司哪家好用
  • java怎么做直播网站站长之家ppt模板
  • 新网站做优化要准备什么电脑清理软件十大排名
  • 建设银行税务网站自媒体推广渠道有哪些
  • 济南网站建设培训班关键词排名点击软件怎样
  • 做电子政务网站怎么建网站
  • 十大网站搜索引擎seo关键词优化方法
  • 申请做网站、论坛版主sem是什么工作