使用EventEmitter进行异步快速应用程序设置单元测试

时间:2014-04-26 17:44:36

标签: javascript node.js unit-testing events asynchronous

我正在尝试对快速应用的设置代码进行单元测试。有些设置是异步的(async_function),因此我为应用程序添加了一种方法,以便在异步设置完成后通过“设置完成”来获取通知。或者'安装失败'事件。

单元测试执行nodeunit setUp函数中的设置,并告诉nodeunit设置完成的回调对test1执行正常,但test2失败。出于某种原因,我会根据运行测试的位置得到不同的错误。

在Webstorm中运行 - nodeunit异步模块错误:
iterator(x.value,function(err,v){
无法阅读财产'价值'未定义的

在cmd行上运行:
$ ../node_modules/nodeunit/bin/nodeunit --reporter verbose test.js
test.js
✔异步快递应用程序设置 - test1
  ✔async_function产生结果
  ✔结果具有测试中指定的值

失败:未经测试(或他们的设置/拆卸):
- 异步快速应用程序设置 - test2

要解决此问题,请确保所有测试都调用test.done()

据我所知,我在正确的地方运行了t.done()。 这可能是我错过的一个明显的错误,我已经看了很长时间了。

有人可以提供建议或帮助吗?

app.js:

var
  async_function     = require( './lib/async_function' ),
  express            = require( 'express' ),
  path               = require( 'path' ),
  app                = express(),
  options            = require( './lib/options' ),
  setupErrorHandlers = require( './lib/error_handlers' );

// do some app setup stuff
app.set( 'views', path.join( __dirname, 'views' ) );
app.set( 'view engine', 'ejs' );
app.disable( "x-powered-by" );

app = async_function( app, options, function ( err ) {
  if ( err ) return app.async_function.setupFailed( err );
  setupErrorHandlers( app );
  app.async_function.setupComplete();
});

module.exports = app;

async_function.js:

var
  events = require( 'events' ),
  setup  = new events.EventEmitter;

var addSetupEventToApp = function ( app ) {
  var fn = {};
  fn.__proto__.then = function ( onSetupComplete, onFailedSetup ) {
    setup.on( 'setup-complete', function () { onSetupComplete(); });
    setup.on( 'setup-failed', function ( error ) { onFailedSetup( error ); });
  };
  fn.__proto__.setupComplete = function ( value ) {
    setup.emit( 'setup-complete', value );
  };
  fn.__proto__.setupFailed = function ( error ) {
    setup.emit( 'setup-failed', error );
  };
  app.async_function = fn;
};

module.exports = function ( app, options, cb ) {
  addSetupEventToApp( app );
  setTimeout( function () {
    if ( app.result ) throw new Error( "AlreadyConfiguredAppError" );
    app.result = options.arg1 + options.arg2;
    cb();
  }, 5000 );
  return app;
};

test.js:

var
  nodeunit   = require( 'nodeunit' ),
  proxyquire = require( 'proxyquire' );

var continueTesting = function() {
  callback();
};
var stopTesting = function( err ) {
  callback( err );
};

exports[ 'asynchronous express app setup' ] = nodeunit.testCase({
  setUp: function ( callback ) {
    proxyquire.noPreserveCache();
    this.app = proxyquire( '../app', {
      './lib/options': {
        arg1: "zxcvbnm",
        arg2: "1234567890"
      }
    });
    this.app.then( continueTesting, stopTesting );
  },

  tearDown: function ( callback ) {
    delete this.app;
    delete this.options;
    proxyquire.preserveCache();
    callback();
  },

  'test1': function ( t ) {
    t.expect( 2 );
    t.ok( ( this.app.result !== undefined ), 'async_function produced a result' );
    t.equal( this.app.result, 'zxcvbnm1234567890', 'result has value specified in the test' );
    t.done();
  },

  'test2': function ( t ) {
    t.expect( 2 );
    t.ok( ( this.app.result !== undefined ), 'async_function produced a result' );
    t.equal( this.app.result, 'zxcvbnm1234567890', 'result has value specified in the test' );
    t.done();
  }
});

0 个答案:

没有答案