Skip to content

Latest commit

 

History

History
312 lines (232 loc) · 5.7 KB

1.1.9 Node.js 测试驱动开发.md

File metadata and controls

312 lines (232 loc) · 5.7 KB

Node.js 测试驱动开发

1.测试优先

    1. 新建目录
testnode
   |
   |---src
   |    |
   |    |---stockfetch.js
   |
   |---test
   |    |
   |    |---stockfetch-test.js
   |
   |---package.json

  • 2.配置 package.json:
{
  "name": "stockfetch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "istanbul cover node_modules/mocha/bin/_mocha"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^3.5.0",
    "istanbul": "^0.4.5",
    "mocha": "^5.2.0",
    "sinon": "^1.17.7"
  }
}
  • 3.金丝雀测试: stockfetch-test.js
/**
 * 金丝雀测试
 */
var expect = require('chai').expect;

describe('unit test1',function(){
  it('shoud pass this canary test',function(){
    expect(true).to.eql(true);
  });
});
  • 4.被测试文件 : stockfetch.js
var StockFetch = function() {
  this.readTickersFile = function(fileName,onError) {
      onError('error reading file:'+ fileName);
  };
};

module.exports = StockFetch;

2.增加 Sinon 沙盒

var expect = require('chai').expect;
var sinon = require('sinon');
var fs = require('fs');
var StockFetch = require('../src/stockfetch.js');

describe('unit test1',function(){
  it('shoud pass this canary test',function(){
    expect(true).to.eql(true);
  });
});

describe('StockFetch test1',function(){
  var stockFetch;
  var sandbox;

  beforeEach(function(){
    stockFetch = new StockFetch();
    sandbox = sinon.sandbox.create();
  });

  afterEach(function(){
    sandbox.restore();
  });

  it('shoud pass this canary test',function(){
    expect(true).to.eql(true);
  });
});


# 引入 sinon ,以便编写 stub,mock;
# beforeEach 中创建 sandbox;
# afterEach 中撤销 stub 或 mock;
  • 编写测试

var expect = require('chai').expect;
var sinon = require('sinon');
var fs = require('fs');
var StockFetch = require('../src/stockfetch.js');

describe('unit test1',function(){
  it('shoud pass this canary test',function(){
    expect(true).to.eql(true);
  });
});

describe('StockFetch test1',function(){
  var stockFetch;
  var sandbox;

  beforeEach(function(){
    stockFetch = new StockFetch();
    sandbox = sinon.sandbox.create();
  });

  afterEach(function(){
    sandbox.restore();
  });

  it('shoud pass this canary test',function(){
    expect(true).to.eql(true);
  });

  /**
   * 增加测试
   */
  it('shoud pass this canary test',function(done){
    var onError = function(){
      expect(true).to.eql(true);
      done();
    };

    sandbox.stub(fs, 'readFile',function(fileName, callBack) {
      callBack(new Error('failed'));
    })

    stockFetch.readTickersFile('invalid', onError);
  });
});

运行测试

npm run dev


> [email protected] test H:\js-test\test-node
> istanbul cover node_modules/mocha/bin/_mocha



  unit test1
    √ shoud pass this canary test

  StockFetch test1
    √ shoud pass this canary test
    √ shoud pass this canary test


  3 passing (73ms)

=============================================================================
Writing coverage object [H:\js-test\test-node\coverage\coverage.json]
Writing coverage reports at [H:\js-test\test-node\coverage]
=============================================================================

=============================== Coverage summary ===============================
Statements   : 100% ( 4/4 )
Branches     : 100% ( 0/0 )
Functions    : 100% ( 2/2 )
Lines        : 100% ( 4/4 )
================================================================================

接下来可以做正向测试, 反向测试

正向测试:

/**
 * 正向测试
 */

it('shoud pass this canary test',function(done){
  var rawData = 'GOOD\nAAPL';
  var parsedData = ['GOOD', 'AAPL'];

  sandbox.stub(stockFetch, 'parseTickers').withArgs(rawData).returns(parsedData);

  sandbox.stub(stockFetch, 'processTickers',function(data) {
    expect(data).to.eql(parsedData);
    done();
  })

  sandbox.stub(fs, 'readFile',function(fileName, callBack) {
    callBack(null, rawData);
  })

  stockFetch.readTickersFile('tickeers.txt');
});
  • 修改 stockfetch.js, 增加方法
var fs = require('fs');

var StockFetch = function() {
  this.readTickersFile = function(fileName,onError) {
    var that = this;

    var processResponse = function(err, data) {
      if (err) {
        onError('error reading file:'+ fileName);
      }else {
        var tickers = that.parseTickers(data.toString());
        that.processTickers(tickers);
      }
    };
    fs.readFile(fileName, processResponse);
  };

  this.parseTickers = function() {};
  this.processTickers = function() {};
};

module.exports = StockFetch;

运行测试

npm run dev

反向测试

  • 修改 stockfetch.js,增加空文件判断
var processResponse = function(err, data) {
  if (err) {
    onError('error reading file:'+ fileName);
  }else {
    var tickers = that.parseTickers(data.toString());
    if (!tickers.length) {
      onError('file:'+ fileName + ' has invalid content');
    }else {
      that.processTickers(tickers);
    }
  }
};
  • 反向测试用例
/**
 * 反向测试
 */

it('shoud return error if given file is empty',function(done){
  var onError = function(err) {
    expect(err).to.eql('file:tickeers.txt has invalid content');
    done();
  };

  sandbox.stub(stockFetch, 'parseTickers').withArgs('').returns([]);

  sandbox.stub(fs, 'readFile',function(fileName, callBack) {
    callBack(null, '');
  })

  stockFetch.readTickersFile('tickeers.txt',onError);
});

运行测试

npm run dev

由于后面使用创建 spike 的方式进行测试,暂时没有再看。。。。。。
实现不是很明确时,先写测试是很困难的,这时候就快速创建一个原型