TDD a React/Redux TodoList 应用程序指南—第 4 部分
TDD a React/Redux TodoList 应用程序指南—第 4 部分
原文:https://medium.com/hackernoon/a-guide-to-tdd-a-react-redux-todolist-app-part-4-edb62e113c9b
第四部分——你现在在这里。
TodoList 组件
为了通过我们失败的 e2e 测试,我们还有几件事要做;有一个.todo-text元素,让它包含我们在表单中提交的文本。
创建文件夹结构src/components/todoList/,然后在test.js编写我们的第一个单元测试,这将允许我们创建我们的组件:
src/components/todoList/test.js
这应该是不言自明的,它非常类似于我们如何开始构建我们的addTodo组件。
index.js中的组件应该返回什么:
src/components/todoList/index.js
Line 4我们将把组件包装在一个<ul>中。
然后让我们测试列表中的 todo:
src/components/todoList/test.js
Line 8 — 13我们创建了我们的todos prop,一个包含一个 todo 的数组,作为带有id和text的对象。
实际上,我们将 todo 作为一个道具传递给组件。
Line 22我们期望我们的todoList将包含一个带有 todo 文本的.todo-text元素。
现在我们只需要让我们的 todo 渲染:
src/components/todoList/index.js
Line 2导入PropTypes供我们验证。
Line 18 — 25我们告诉我们的组件,它将接收一个名为todos的prop,它将是一个对象数组,它的id将是一个数字,text将是一个字符串,一切都是必需的。 反应道具类型验证 。
我们将todos prop 传入我们的实际组件。
Line 5 — 8我们map通过我们的数组,返回一个li,它的内容是todo.text,它有一个todo.id的key,React需要key来更有效地知道如何重新渲染 DOM,如果你没有它,你将在开发中得到一个控制台警告。
Line 11 — 15我们返回我们的ul包装器,其中包含我们状态中每个 todo 的所有li。
- Git 提交。
- 储存库的状态。
显示待办事项
此时,我们的TodoList组件知道如何呈现自己,因此可以连接到我们的主应用程序。
src/App.js
Line 5导入我们的TodoList组件。
Line 18 — 23为其提供适当的验证。
Line 8将我们的 todos 数组作为一个prop从状态输入到我们的应用程序中,这样我们就可以将它传递下去。多亏了line 26,我们才把它变成了prop。
Line 12将TodoList组件添加到我们的App中,并将todos从状态传递给它。
我们现在得到一个测试错误,因为我们已经告诉组件它需要一个todos数组,但是还没有传入:

所以我们做出了改变:
src/App.test.js
简单地传递一个空数组给我们的道具,这将停止我们的抱怨。我们不想在父级对子组件进行单元测试。
现在,如果我们在浏览器中查看我们的应用程序,我们会发现我们实际上可以显示那些我们一直存储在状态中的可爱的待办事项。万岁。

现在我们的 e2e 测试应该通过了:

删除待办事项
首先,我们编写 e2e 测试:
e2etests/test.js
将上面的Line 12 — 21添加到你的 e2e 测试中。
该测试运行与之前相同的程序,然后单击.todo-delete元素,然后期望选择器的state等于“失败”。如果它存在(没有被删除),就等于“成功”。
我喜欢通过编写动作、缩减器、创建组件,然后将其添加到应用程序来实现功能。
因此,让我们测试一下正确的操作。首先让我们创建一个适当的常数:
src/constants/index.js
Line 3我们新的 DELETE_TODO 常量。
然后,在action中,我们只需要知道删除一个 todo 将是它唯一的id。
src/actions/test.js
然后添加代码使其通过:
src/actions/index.js
现在让我们对我们的缩减器功能进行单元测试:
src/reducers/test.js
现在看来,这应该很有意义了。我们给我们的reducer一个包含 todo 的startingState,将它传递给我们刚刚创建的action,它将从存储中删除该 todo,并期望返回的状态确实不包含该 todo。
我们现在需要在我们的reducer中添加另一个case来处理这个问题:
src/reducers/index.js
当遇到 DELETE_TODO action.type时,我们返回一个包含所有现有...state的新状态,我们覆盖todos数组,使其成为一个过滤列表,其中todo.id与action.id不同。因此所有的todo都不是我们想要删除的。
那很容易,不是吗?
现在让我们测试一下我们的组件能不能让我们删除一个 todo:
src/components/todoList/test.js
Line 1将jest添加到 eslint 异常中。
Line 8为我们的删除功能创建一个模拟函数。
将我们之前的单个todos道具重构为一个包含我们需要的所有道具的对象。
Line 20让我们的component浅层渲染,把之前指定的props全部解包。
测试点击一个.todo-delete元素确实调用了我们的deleteTodo函数。
然后是通过测试的代码:
src/components/todoList/index.js
Line 36验证我们的deleteTodo道具。
Line 4将它传递给我们的组件。
Line 8 — 14添加一个“删除”按钮,该按钮将调用deleteTodo函数,并将todo.id作为onClick事件的参数。
现在,我们需要通过应用程序将它连接到我们的用户界面:
src/App.js
Line 36 — 38创建将分派适当动作的deleteTodo道具。
Line 24验证。
Line 8将其添加到我们组件的道具中。
Line 12将其添加到TodoList组件中。
而且真的就是这么简单。单元测试和 e2e 测试应该通过,功能应该在我们的应用程序在浏览器中工作。

取消删除待办事项
如果你还和我在一起,那么你做得很好,绝对不是一个新手!所以是时候来点小挑战了。我不会告诉你怎么做,为什么不自己试一试呢?
想想你需要什么。
就在上面,你可以删除待办事项的所有功能,取消删除也一样。还要考虑如何、在哪里以及何时存储你最近删除的待办事项。有了这个地方,它应该点击!
做这件事不会太难,可能需要半个小时或几个小时,但你能做到。尝试和 TDD 它一个坚实的挑战。
然后看看我是如何做到的:
- Git 提交。
- 存储库的状态。
禁用按钮
因此,我们的应用程序在某种程度上是可行的,我们测试过的东西也是可行的。但是如果你尝试使用它,你可能会发现一些我们没有编码的错误。如果你愿意,你可以试着修改它们并添加更多的功能,但是在你这么做之前,我要给你的最后一个挑战是,当不适合点击按钮时,禁用‘添加待办事项’和‘取消删除’按钮。
想一想你可以如何实现这一点,谷歌一下,试一试。我们都知道你能做到!
你做完后,看看我是怎么做的。我绝对不会说有正确或错误的方法,只是不同的方法:
设计它
作为一个前端,我很痛苦地称之为风格的,但我猜这不是一个 CSS 教程。如果你想把它变漂亮,那就穿上你的靴子。这正是我的样子:

High production value
部署到 Heroku
这是可选的,只是为了好玩,但如果你想免费轻松地在线部署你的应用程序,Heroku 提供了一个快速解决方案。如果你愿意的话,这将允许你使用生产版本和你自己的 CI/CD 管道。
首先与 Heroku 建立联系。
然后按照 heroku-buildpack 的说明进行反应。
点击在线访问应用程序。
撰写自述文件
我用简单的方法列出了如何设置、运行和测试我们的应用程序。
以前的零件
第四部分——你现在在这里。
就这样…
是的,确实是。有什么反馈吗?请在下方留言。
我出 9000。