美文网首页
node.js 常用技术(二) 测试相关

node.js 常用技术(二) 测试相关

作者: Oo晨晨oO | 来源:发表于2017-12-05 23:46 被阅读13次

    node.js的测试是非常重要的, 通常要写一个函数就要写出其对应的测试
    通常, node.js测试

    • 可以使用mocha测试库
    • 断言使用chai断言库

    步骤

    1. 导入测试库

    • yarn add mocha --save-dev: 在项目中导入测试库
    • 工程根目录新建test文件夹

    mocha会在项目中寻找test文件夹, 默认文件夹里的文件都是测试文件. 所以我们可以在项目工程根目录新建一个test文件夹, 把我们的测试文件都放入test文件夹中. 运行测试的时候, mocha会自动去test文件夹中执行测试文件

    2. 导入断言库

    我们要进行测试, 需要有断言来判断运行正确与否
    可以使用chai断言库

    • yarn add chai --save-dev: 在项目中导入断言库

    3. 编写测试方法

    • 首先在test文件夹里新建js测试文件
    • 然后在测试文件中使用describe建立测试
    • describe第二个回调方法参数中加入context建立测试场景
    • context测试场景的第二个回调方法参数中加入it建立具体测试

    context不是必须的, describe中还有before, after, beforeEach, afterEach四个钩子方法

    4. 运行测试

    终端执行: ./node_modules/mocha/bin/mocha
    或者在package.json中配置

    "scripts": {
        "test": "./node_modules/mocha/bin/mocha"
      },
    

    然后进入工程根目录执行 npm test 或者 npm run test

    测试框架与断言框架的使用

    1. describe的钩子方法 与 context, it的用法

    describe("demo01", () => {
      describe("方法1", () => {
        before(() => {
          console.log("执行之前....");
        })
        after(() => {
          console.log("执行之后....");
        })
        beforeEach(() => {
          console.log("每条之前........");
        })
        afterEach(() => {
          console.log("每条之后........");
        })
        context("情景1", () => {
          it("测试1", () => {
    
          })
          it("测试2", () => {
    
          })
          it("测试3", () => {
    
          })
        })
      })
    })
    

    2. assert风格断言

    const chai = require('chai')
    const assert = chai.assert
    
    describe("assert断言测试", () => {
      it("使用断言测试1", () => {
        let value = "hahaha"
        assert.typeOf(value, 'string')
        assert.equal(value, 'hahaha')
        assert.lengthOf(value, 6)
      })
    })
    

    3. should风格断言

    const chai = require('chai')
    const should = chai.should()
    describe("should断言", () => {
      it("使用should断言测试1", () => {
        let value = "hello"
        value.should.exist
        value.should.be.a("string")
        value.should.equal("hello")
        value.should.not.equal("你好")
        value.should.have.length(5)
      })
    })
    

    也可以使用链式写法写成如下这样

    describe("should断言", () => {
      it("使用should断言测试1", () => {
        let value = "hello"
        // value.should.exist
        // value.should.be.a("string")
        // value.should.equal("hello")
        // value.should.not.equal("你好")
        // value.should.have.length(5)
        value.should.exist.and.be.a('string').and.equal('hello').and.have.length(5)
      })
    })
    

    4. except风格断言

    const expect = chai.expect
    describe("expect断言", () => {
      it("使用expect断言测试1", () => {
        let value = "hello"
        let number = 3
        expect(number).to.be.at.least(3)
        expect(number).to.be.at.most(5)
    
        expect(value).to.exist
        expect(value).to.be.a('string')
        expect(value).to.equal('hello')
        expect(value).to.not.equal('你好')
        expect(value).to.have.length(5)
      })
    })
    

    使用示例

    这里有几个方法要测试

    const https = require("https")
    
    class Demo {
      // 要测试的普通方法
      subTotal(unitPrice, quantity) {
        return unitPrice * quantity
      }
      // 要测试的延时方法
      waitTwoSec(data, func) {
        setTimeout(() => {
          func(data)
        }, 2000)
      }
      // 要测试的网络访问方法
      fetchData(api, callBack) {
        let requestUrl = `https://api.douban.com/v2/movie/${api}`
        https.get(requestUrl, (response) => {
          let responsData = ''
          response.setEncoding("utf8")
          response.on("data", (chunk) => {
            responsData += chunk
          })
          response.on("end", () => {
            callBack(JSON.parse(responsData))
          })
        })
      }
      // 要测试的抛出异常
      testThrow(content) {
        if (content === 'error') {
          throw new Error('throw our error')
        }
      }
      // 要测试的sinon spies方法跟踪
      send(data) {
        this.logMessage(data)
      }
    
      logMessage(data) {
        console.log(data);
      }
    }
    
    module.exports = Demo
    
    

    1. 测试普通方法

    const chai = require('chai')
    const expect = chai.expect
    const Demo = require('../lib/demo-02')
    
    let demo = new Demo()
    
    describe("总价测试", function() {
      it("单价10 数量3 总价30", () => {
        let subTotal = demo.subTotal(10, 3)
        expect(subTotal).to.equal(30)
      })
    })
    

    2. 测试延时方法

    • 注意, describe方法里面默认2000毫秒之后超时. 如果要测试延时超过2000毫秒的, 要在describe回调方法中进行设置
    • 为了防止测试方法先于被测试的延时方法结束, 要在回调方法中传入一个done方法, 在延时方法结束后执行done()方法, 结束回调方法
    // 这里设置这个测试经过多长时间超时
      this.timeout(12000)
    // 这个done用来防止测试方法在延时方法之前结束
      it("测试两秒延时", (done) => {
        demo.waitTwoSec("Hello", (res) => {
          expect(res).to.equal("Hello")
          done()
        })
      })
    

    3. 测试访问网络数据方法

    it("测试豆瓣包不包含subjects", function(done){
        demo.fetchData("top250", function(data){
          expect(data).to.have.property("subjects")
          done()
        })
      })
    

    4. 测试能否抛出异常

    it("测试能否抛出异常", function(){
        expect(function(){
          demo.testThrow("error")
        }).to.throw('throw our error')
      })
    

    5. 使用sinon Spies来测试跟踪方法

    it("使用sinon来测试跟踪方法", function(){
        // 为logMessage方法添加各种特殊属性
        sinon.spy(demo, 'logMessage')
        demo.send("hello")
        // console.log(demo.logMessage);
        expect(demo.logMessage.calledOnce).to.be.true
        expect(demo.logMessage.firstCall.args[0]).to.equal('hello')
        demo.logMessage.restore()
      })
    

    6. 使用sinon stub来模拟函数的行为

    it("使用sinon stub来测试方法", function(){
        var stub = sinon.stub(demo, 'logMessage')
        stub.withArgs('hello').returns('hello')
        demo.send('hello')
        expect(stub.returnValues[0]).to.equal('hello')
        stub.restore()
      })
    

    相关文章

      网友评论

          本文标题:node.js 常用技术(二) 测试相关

          本文链接:https://www.haomeiwen.com/subject/gkuhixtx.html