我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Node.js中怎么实现单元测试

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Node.js中怎么实现单元测试

Node.js中怎么实现单元测试,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

为啥需要单元测试?

所谓单元测试,就是对某个函数或者API进行正确性验证。来看个简单的例子add1.js:

function add(a, b) {return a + b;}

没错,我写了一个加法函数。这有啥好测的呢?不妨用node执行一下:

> add = function(a, b){return a + b}[Function: add] > add(4) NaN

当add函数仅给定一个参数4的时候,a为4,b为undefined,两者相加为NaN。

  • 你考虑过只有一个参数的场景吗?

  • 给定一个参数时,NaN是你想要的结果吗?

  • 如果参数不是整数怎么办?

这时,就需要单元测试来验证各种可能的场景了。

如果我把add函数定义为两个整数相加,而其他输入则返回undefined,那么正确的代码add2.js应该是这样的:

function add(a, b) {if (typeof a === "number" && typeof b === "number")    {return a + b;    }else{return undefined;    }}

发现一个有趣的现象,我们写代码的时候很容易陷入思维漏洞,而写测试的时候往往会考虑各种情况,这就是所谓的TDD(Test-Driven-Development: 测试驱动开发)的神奇之处。因此,进行一定的单元测试是十分必要的:

  • 验证代码的正确性

  • 避免修改代码时出错

  • 避免其他团队成员修改代码时出错

  • 便于自动化测试与部署

测试框架 - Mocha

下面的测试代码test2.js用于测试add2.js。这里使用了测试框架Mocha以及Node.js自带的断言库Assert。

var add = require("../add2.js");var assert  = require("assert");// 当2个参数均为整数时it("should return 3", function() {var sum = add(1, 2);    assert.equal(sum, 3);});// 当第2个参数为String时it("should return undefined", function() {var sum = add(1, "2");    assert.equal(sum, undefined);});// 当只有1个参数时it("should return undefined", function() {var sum = add(1);    assert.equal(sum, undefined);});

测试代码中使用了测试框架Mocha提供的it函数,3个it函数分别测试了3种不同的案例(test  case)。it函数的第1个参数为字符串,用于描述测试,一般会写期望得到的结果,例如”should return 3”;  而第2个参数为函数,用于编写测试代码,一般是先调用被测试的函数或者API,获取结果之后,使用断言库判断执行结果是否正确。

测试代码中使用了Node.js自带的断言库Assert的assert.equal函数,用于判定add函数返回的结果是否正确。assert.equal成功时不会发生什么,而失败时会抛出一个AssertionError。不妨使用node测试一下:

> assert  = require("assert");> assert.equal(1, 1);undefined> assert.equal(1, 2);AssertionError: 1 == 2at repl:1:8at sigintHandlersWrap (vm.js:22:35)    at sigintHandlersWrap (vm.js:96:12)    at ContextifyScript.Script.runInThisContext (vm.js:21:12)    at REPLServer.defaultEval (repl.js:313:29)    at bound (domain.js:280:14)    at REPLServer.runBound [as eval] (domain.js:293:12)    at REPLServer.<anonymous> (repl.js:513:10)    at emitOne (events.js:101:20)    at REPLServer.emit (events.js:188:7)

原理:

我们按照Mocha的it函数编写一个个测试案例,然后Mocha负责执行这些案例;当assert.equal断言成功时,则测试案例通过;当assert.equal断言失败时,抛出AssertionError,Mocha能够捕获到这些异常,然后对应的测试案例失败。

使用mocha执行test2.js:

mocha test/test2.js

下面为输出,表示测试案例全部通过

✓ should return 3✓ should return undefined✓ should return undefined3 passing

而当我们使用test1.js测试add1.js时,则后面2个测试案例失败:

✓ should return 3  1) should return undefined  2) should return undefined  1 passing (14ms)  2 failing  1)  should return undefined:     AssertionError: '12' == undefined  at Context.<anonymous> (test/test1.js:18:12)  2)  should return undefined:     AssertionError: NaN == undefined  at Context.<anonymous> (test/test1.js:25:12)

断言库 - Should

Node.js自带的断言库Assert提供的函数有限,在实际工作中,Should等第三方断言库则更加强大和实用。

我写了一个merge函数merge.js,实现了类似于_.extend()与Object.assign()的功能,用于合并两个Object的属性。

function merge(a, b) {if (typeof a === "object" && typeof b === "object")    {for (var property in b)        {            a[property] = b[property];        }return a;    }else{return undefined;    }}

然后我使用Should写了对应的测试代码test3.js:

require("should");var merge = require("../merge.js");// 当2个参数均为对象时it("should success", function() {var a = {        name: "Fundebug",        type: "SaaS"};var b = {        service: "Real time bug monitoring",        product:        {            frontend: "JavaScript",            backend: "Node.js",            mobile: "微信小程序"}    };var c = merge(a, b);    c.should.have.property("name", "Fundebug");    c.should.have.propertyByPath("product", "frontend").equal("JavaScript");});// 当只有1个参数时it("should return undefined", function() {var a = {        name: "Fundebug",        type: "SaaS"};var c = merge(a);    (typeof c).should.equal("undefined");});

测试代码稍微有点长,但是使用Should的只有三处:

c.should.have.property("name", "Fundebug");c.should.have.propertyByPath("product", "frontend").equal("JavaScript");(typeof c).should.equal("undefined");

可知Should能够:

  • 验证对象是否存在某属性,并验证其取值

  • 验证对象是否存在某个嵌套属性,并使用链式方式验证其取值

那么Should为什么不能直接验证c的取值为undefined呢?比如这样写:

c.should.equal(undefined); // 这样写是错误的

原理:

Should会为每个对象添加should属性,然后通过该属性提供各种断言函数,我们可以使用这些函数验证对象的取值。对于undefined,Should无法为其添加属性,因此失败。

通过node验证发现,导入Should之后,空对象a增加了一个should属性。

> a = {}> typeof a.should'undefined'> require("should")> typeof a.should'object'

测试HTTP接口 - SuperTest

Node.js是用于后端开发的语言,而后端开发其实很大程度上等价于编写HTTP接口,为前端提供服务。那么,Node.js单元测试则少不了对HTTP接口进行测试。

我用Node.js自带的HTTP模块写了一个简单的HTTP接口server.js

var http = require("http");var server = http.createServer((req, res) =>{    res.writeHead(200,    {"Content-Type": "text/plain"});    res.end("Hello Fundebug");});server.listen(8000);

按照Mocha的原理,测试HTTP接口并不难: 访问接口; 获取返回数据; 验证返回结果。使用Node.js原生的http与assert模块就可以了test4.js:

require("../server.js");var http = require("http");var assert = require("assert");it("should return hello fundebug", function(done) {    http.get("http://localhost:8000", function(res)     {        res.setEncoding("utf8");        res.on("data", function(text)         {            assert.equal(res.statusCode, 200);            assert.equal(text, "Hello Fundebug");            done();        });    });});

值得稍微注意的一点是,http.get访问HTTP接口是一个异步操作。Mocha在测试异步代码是需要为it函数添加回调函数done,在断言结束的地方调用done,这样Mocha才能知道什么时候结束这个测试。

既然Node.js自带的模块就能够测试HTTP接口了,为什么还需要SuperTest呢?不妨先看一下测试代码test5.js:

var request = require("supertest");var server = require("../server.js");var assert = require("assert");it("should return hello fundebug", function(done) {    request(server)        .get("/")        .expect(200)        .expect(function(res)         {            assert.equal(res.text, "Hello Fundebug");        })        .end(done);});

对比两个测试代码,会发现后者简洁很多。

原理

SuperTest封装了发送HTTP请求的接口,并且提供了简单的expect断言来判定接口返回结果。对于POST接口,使用SuperTest的优势将更加明显,因为使用Node.js的http模块发送POST请求是很麻烦的。

要做多少单元测试?

本文所写的单元测试案例,都很简单。然而,在实际工作中,单元测试是一个很头痛的事情。修改了代码有时意味着必须修改单元测试,写了新的函数或者API就得写新的单元测试。如果较真起来,单元测试可以没完没了地写,但这是没有意义的。而根据二八原理,20%的测试可以解决80%的问题。剩下的20%问题,事实上我们是力不从心的。换句话说,想通过测试消除所有BUG,是不现实的。

因此,对生产代码进行实时错误监测是非常有必要的,这也是我们Fundebug努力在做的事情。

看完上述内容,你们掌握Node.js中怎么实现单元测试的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Node.js中怎么实现单元测试

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Node.js中怎么实现单元测试

Node.js中怎么实现单元测试,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。为啥需要单元测试?所谓单元测试,就是对某个函数或者API进行正确性验证。来看个简单的例子add1.
2023-06-17

Django中怎么实现单元测试

在Django中,可以使用Django提供的TestCase类来编写单元测试。下面是一个示例:创建一个测试类,并继承自django.test.TestCase:from django.test import TestCaseclass My
Django中怎么实现单元测试
2024-03-06

python中怎么实现unittest单元测试

python中怎么实现unittest单元测试,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。说明1、导入unittest模块。2、导入被测对象。3、创建测试类unittest.
2023-06-20

GO中的单元测试怎么实现

这篇“GO中的单元测试怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“GO中的单元测试怎么实现”文章吧。
2023-07-04

android单元测试怎么实现

Android单元测试可以通过使用JUnit框架和Android Testing Support Library来实现。以下是实现Android单元测试的步骤:1. 配置Gradle:在项目的`build.gradle`文件中添加以下依赖项
2023-08-29

Hibernate单元测试怎么实现

这篇文章主要介绍“Hibernate单元测试怎么实现”,在日常操作中,相信很多人在Hibernate单元测试怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate单元测试怎么实现”的疑惑有所
2023-06-17

Java中怎么实现单元测试与集成测试

Java中怎么实现单元测试与集成测试,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Maven测试代码结构的组织我们知道在Maven工程结构中“src/test”目录是专门用
2023-06-16

SpringBoot+TestNG单元测试怎么实现

这篇“SpringBoot+TestNG单元测试怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot+
2023-06-08

怎么实现Python的add5()单元测试

本篇内容介绍了“怎么实现Python的add5()单元测试”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!TestAdd5类由unittest
2023-06-17

在Android Studio中实现单元测试

我们写了一个类,我们只希望测试下其算法是否正确,没必要真正运行一个完整的 APP,做单元测试即可。在 Android Studio 中,我们在 java 文件夹下,可以看到一个以“(test)”结尾的包,其中有一个E
2022-06-06

怎么在Android中利用Activity实现单元测试

这期内容当中小编将会给大家带来有关怎么在Android中利用Activity实现单元测试,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。对Acitivity的测试对于Activity,我们大致有两种测试需求
2023-05-30

Spring Boot中怎么利用JUnit 5实现单元测试

这篇文章给大家介绍Spring Boot中怎么利用JUnit 5实现单元测试,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. 忽略测试用例执行JUnit 4:@Test @Ignore public void t
2023-06-16

idea单元测试自动生成怎么实现

实现自动生成单元测试的方法可以分为以下几个步骤:静态代码分析:通过静态代码分析工具(如静态代码分析器、AST解析器等),对待测试的代码进行解析和分析,提取出代码的结构、函数的参数和返回值等信息。自动化测试框架:搭建一个自动化测试框架,用于生
2023-10-22

SpringBoot单元测试如何实现

这篇文章将为大家详细讲解有关SpringBoot单元测试如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。demo(SpringBoot 项目)被测试类:import org.springframew
2023-06-25

SpringBoot中怎么进行单元测试

在SpringBoot中进行单元测试可以使用JUnit和Spring Boot Test框架。以下是一个简单的示例:首先,在pom.xml文件中添加JUnit和Spring Boot Test的依赖:
SpringBoot中怎么进行单元测试
2024-03-07

Golang实现单元测试中的逻辑层

前面我们完成了最麻烦的数据层的单元测试,今天我们来看看单元测试中最容易做的一层,数据逻辑层,也就是我们通常说的service或者biz等
2023-03-10

Golang实现单元测试中的接口层

接口层主要负责的就是请求的处理,最常见的就是 HTTP 请求的处理。这篇文章主要为大家介绍了Golang如何实现单元测试中的接口层,需要的可以参考一下
2023-03-11

怎么在python中创建单元测试

本篇内容主要讲解“怎么在python中创建单元测试”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在python中创建单元测试”吧!让我们先从为什么要做测试开始:1、减少手动测试的需求因为测试
2023-07-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录