专栏首页京程一灯JavaScript 测试教程–part 3:测试 props,挂载函数和快照测试[每日前端夜话0xE9]

JavaScript 测试教程–part 3:测试 props,挂载函数和快照测试[每日前端夜话0xE9]

正文共:1489 字

预计阅读时间:6 分钟

作者:Marcin Wanago

翻译:疯狂的技术宅

来源:wanago.io

在上一篇教程中,我介绍了使用 Enzyme 测试 React 组件的基础知识。今天,将进行更深入的研究,并学习如何测试 props,如何(以及为什么)使用 mount 函数以及什么是快照测试。开始吧!

测试 props

在上一篇文章中,我们测试了通过一些 props 的结果。但是实际上,我们可以直接测试 props。让我们回到上次的 ToDoList 组件,不过这次要用一个新的 Task 组件。

ToDoList.js
import React from 'react';
import Task from "../Task/Task";

const ToDoList = (props) => {
  return (
    <ul>
      {
        props.tasks.map(task =>
          <Task key={task.id} id={task.id} name={task.taskName}/>
        )
      }
    </ul>
  )
};

export default ToDoList;

我们将要测试 ToDoList 组件是否渲染 Task 组件,并将任务名称传递给他们。

ToDoList.test.js
import React from 'react';
import { shallow } from 'enzyme';
import ToDoList from './ToDoList';

describe('ToDoList component', () => {
  describe('when provided with an array of tasks', () => {
    it('passes them to the Task components', () => {
      const tasks = [
        {
          id: 0,
          name: 'Wash the dishes'
        },
        {
          id: 1,
          name: 'Make the bed'
        }
      ];
      const toDoListInstance = shallow(
        <ToDoList tasks={tasks}/>
      );
      toDoListInstance.find('Task').forEach(taskInstance => {
        const taskProps = taskInstance.props();
        const matchingTask = tasks.find(task => task.id === taskProps.id);
        expect(taskProps.name).toBe(matchingTask.name);
      })
    })
  });
});

通过测试,我们可以确保 Task 组件能够从 ToDoList 接收正确的 props。

由于 toDoListInstancetaskInstance 均继承自 ShallowWrapper,因此我们可以调用 props 函数。同样,你可以检查和更改状态。有关可用函数的完整列表,请访问文档【https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md】。

但是如果我们想测试 Task 组件中 <li> 标记的实际内容怎么办?

toDoListInstance.find('Task').forEach(taskInstance => {
  const taskProps = taskInstance.props();
  const matchingTask = tasks.find(task => task.id === taskProps.id);
  const listItem = taskInstance.first('li');
  expect(listItem.text()).toBe(matchingTask.name);
})

运行测试后你将会看到一个错误:

 FAIL  app/components/ToDoList/ToDoList.test.js
  ● ToDoList component › when provided with array of tasks › passes them to the Task components

    expect(received).toBe(expected) // Object.is equality

    Expected: "Wash the dishes"
    Received: "<Task />"

      23 |         const matchingTask = tasks.find(task => task.id === taskProps.id);
      24 |         const listItem = taskInstance.first('li');
    > 25 |         expect(listItem.text()).toBe(matchingTask.name);
         |                                 ^
      26 |       })
      27 |     })
      28 |   });

使用 mount 函数渲染

失败了,因为我们在这里用了“浅渲染”。在这种情况下子组件将根本不会被渲染。所以上面的测试失败了,你需要了解“浅渲染”的局限性。

Mount 模拟了 DOM 的实现,而 Jest 默认使用 jsdom。你可以通过 testEnvironment 属性【https://jestjs.io/docs/en/configuration.html#testenvironment-string】进行更改。

在早期版本的Enzyme中,在浅层渲染期间未调用生命周期方法。但是在 Enzyme 3.0 中发生了变化

const toDoListInstance = mount(
  <ToDoList tasks={tasks}/>
);

运行上面的代码将使整个 ToDoList 组件及其所有子组件渲染。前面失败的测试现在将会通过。

由于 mount 函数可渲染更多内容并模仿实际的 DOM,所以测试将会花费更多时间。使用 mount 函数可能意味着你是在进行单元测试,而现在在进行集成测试。正是由于这个事实,使用 mount 函数能够测试这些组件是否可以协同工作,而不仅仅是单独的单元测试。

要弄清楚单元测试集成测试的区别,请参见本教程第一部分

在测试与 DOM 的交互或高阶组件时,它也被证明是有用的。

要了解有关高阶组件的更多信息,请查看官方指南【https://reactjs.org/docs/higher-order-components.html】和 David Kopal 的文章【https://medium.freecodecamp.org/higher-order-components-the-ultimate-guide-b453a68bb851】

快照测试

在测试中使用快照是非常有用的。在测试期间,将渲染组件并创建其快照。它包含渲染组件的整个结构,应该与测试本身一起提交给存储库。再次运行快照测试时,新的快照将与旧的进行比较。如果它们不同,则测试将失败。这将帮助你确保用户界面不会被意外更改。

ToDoList.test.js
import React from 'react';
import { shallow } from 'enzyme';
import ToDoList from './ToDoList';

describe('ToDoList component', () => {
  describe('when provided with an array of tasks', () => {
    it('should render correctly', () => {
      const tasks = [
        {
          id: 0,
          name: 'Wash the dishes'
        },
        {
          id: 1,
          name: 'Make the bed'
        }
      ];
      const toDoListInstance = shallow(
        <ToDoList tasks={tasks}/>
      );
      expect(toDoListInstance).toMatchSnapshot();
    });
  });
});

运行上面的代码将会创建一个名为 ToDoList.test.js.snap 的文件

ToDoList.test.js.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ToDoList component when provided with array of tasks should render correctly 1`] = `
<ul>
  <Task
    id={0}
    key="0"
    name="Wash the dishes"
  />
  <Task
    id={1}
    key="1"
    name="Make the bed"
  />
</ul>
`;

要更新所有失败的快照,你可以使用 `-u 标志( --updateSnapshot的别名)运行 Jest。命令为 npm run test -- -u

你还可以在 watch 模式下运行 Jest,这能够允许你一个接一个地更新所有有冲突的快照。为了做到这一点,请运行 npm run test---watchAll,然后选择 i 交互式地更新失败的快照。官方 Jest 文档【https://jestjs.io/docs/zh/snapshot-testing】中有一个很好的动画演示了这个过程。

快照测试可以成为跟踪组件更改的非常强大的工具。这样可以防止你以意想不到的方式更改组件,从而迫使你查看所做的更改并接受或解决问题。因此它可用作监视代码的工具。

摘要

在本文中,我们介绍了对组件的 props 进行测试的过程,并了解了 mount 函数和 浅渲染 之间的区别。除此之外,我们还介绍了快照测试,它是跟踪组件渲染方式变化的有用工具。在下一篇文章中,我们还将介绍组件的模拟交互,敬请关注!

原文:https://wanago.io/2018/09/10/javascript-testing-tutorial-part-three-testing-props-the-mount-function-and-snapshot-tests/

下面夹杂一些私货:也许你和高薪之间只差这一张图

2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。

愿你有个好前程,愿你月薪30K。我们是认真的 !

在公众号内回复“体系”查看高清大图

本文分享自微信公众号 - 前端先锋(jingchengyideng)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你可能需要了解下Laravel集合

    集合通过 Illuminate\Support\Collection 进行实例,Laravel的内核大部分的参数传递都用到了集合,但这并不代表集合就是好的。La...

    CrazyCodes
  • 通过单元测试和 JaCoCo 提高 Java 代码覆盖率和质量

    作为一家技术公司,那么公司技术的快速发展是很有必要的。但同时,我们不能为了稍微快一点地交付代码质量而牺牲代码质量。编写测试是保证代码质量,同时保持快速发布计划的...

    breezedancer
  • 是时候了解下Travis CI是什么了

    有些朋友一直疑惑Travis CI是个什么东西,网络上搜索后得知的答案是自动测试,自动发布。自动xx 这个名词貌似非常流行,这也是DevOps的一部分,什么?D...

    CrazyCodes
  • MySQL实际应用的两个案例

    今天早晨,有个业务方提了个需求,是需要把一个表里的字段从date格式直接变成int格式,目的是为了去掉日期格式中间的短横线,类似2019-09-01变...

    AsiaYe
  • 深度学习解决手写数字的图片识别

    本篇使用TensorFlow框架,利用MNIST手写数字数据集来演示深度学习的入门概念。其训练集共有60000个样本(图片和标签),测试集有10000个样本。手...

    用户6021899
  • 来 ! 玩玩PHPUnit的数据库测试 (上)

    大家好,我是CrazyCodes,今天我们来聊聊50%(不完全统计,不必纠结比例 ?)的程序员都感觉没有啥用的数据库测试。

    CrazyCodes
  • sql_mode之only_full_group_by

    今天上班的时候,业务方问了我这样一个问题:能不能把线上的sql_mode值改为和测试环境一致?因为我们在测试环境上写的sql在线上可能会出错,原因是线上...

    AsiaYe
  • 程序员自己能写测试的话,还要测试人员做什么?测试表示很无辜

    本篇想要通过探讨这些问题背后的困难,来说明程序员怎样通过编写自测代码更有效率的进行开发。

    IT大咖说
  • Flask 项目参数配置以及读取

    在Django项目中,配置的参数都是在settings.py文件中进行设置,如果需要使用参数,则可以导入from django.conf import sett...

    Devops海洋的渔夫
  • MySQL大表删除工具pt-osc​

    早上刚来,有个业务需求,是要变更一张表的表结构,我登陆到服务器上看了看之前的变结构,大概信息如下:

    AsiaYe

扫码关注云+社区

领取腾讯云代金券