任务 3:Redux 数据流测试

Hey,你好,我是 JimmyLv 吕靖,这是你开始 前端 TDD 练习的第 17 天。今天你将会开始进入 Redux Store,对 Redux 的数据流进行测试,驱动出更好的状态管理,把代码放在该放的位置。

在上一个任务当中你已经用上了 React Router 的几个官方 Hook,其实,你会发现,你写 React 的思路就变成了:先驱动出组件树拆分,组件就是函数,那这个函数可能时不时需要来点儿副作用,比如说跳转一下路由,或者获取一下数据,那就用钩子(Hook)把外部代码"钩"进来。

也许你之前已经用上了 useState 来做一些简单的状态管理,但是你现在需要一个全局的状态管理器来进行状态管理,此时就不能直接去 set 某个 state 的值啦。于是乎,useDispatch 就被拿来触发(dispatch)一个 action,然后再去 Redux store 改变 state 的值:

import React from 'react'
import { useDispatch } from 'react-redux'

export const CounterComponent = ({ value }) => {
  const dispatch = useDispatch()

  return (
    <div>
      <span>{value}</span>
      <button onClick={() => dispatch({ type: 'counter/increment' })}>Increment counter</button>
    </div>
  )
}

然后当你需要某个状态的时候,便可以通过 useSelector 再从 Redux store 取回来,非常方便的同时,selector 还能帮你做一次获取数据的缓存,如果是同样的输入参数,因为是纯函数就必然会计算返回同样的结果,所以干脆就直接返回上一次的结果得了。

import React from 'react'
import { useSelector } from 'react-redux'

export const TodoListItem = (props) => {
  const todo = useSelector((state) => state.todos[props.id])
  return <div>{todo.text}</div>
}

练习目标

  • 使用 redux-saga 处理数据请求等异步 Action

  • 先写 redux-saga-test-plan 测试,再写 Redux model 数据逻辑

  • 学习 Jest Mock API 及异步测试方法 (mock() fn() spyOn())

  • 测试 selectors 与 useSelector,最简单的纯 JavaScript 逻辑单测

使用 redux-saga-test-plan 集成测试 Redux store

如何测试 connect 到 Redux 的 React 组件

本次任务的练习要求

  • redux-saga over redux-thunk(利于测试)

  • 组件化拆分,不能有重复逻辑(通过 React Hook 提取)

  • 实现 Redux 数据流,并保持 Outside-In TDD 的节奏

  • 别忘了 Cypress E2E 测试还在运行着呢!

也请你思考一下

什么时机,回到 Cypress 检查页面元素是否正确显示?

如果有必要的话,你还可以检查一下是否调用后端 API,但我建议在 E2E 层面只关心真实用户会怎么用你的网页,普通用户可能并不关心浏览器是否发送 HTTP request。

最后更新于