javascript - 组织中型 JavaScript 客户端应用程序的代码以进行测试

标签 javascript jquery backbone.js qunit

我正在使用backbone 及其 friend jquery 和underscore 构建一个中等大小的应用程序。我的计划是使用QunitJS创建单元测试。

我已经对该应用程序进行了概念验证,因此我基本上已经很好地掌握了代码的外观,而无需对其进行测试。看起来像这样:

(function() {
  // prepare some model
  var Query = BackboneModel.extend({});
  query = new Query();

  // register some events
  $('body.something').click(function() {
    query.set('key', 'value');
    # ...
  });

  // create some backbone view
  var QueryView = Backbone.View.extend({...})

  // init backbone view
  query.view = new QueryView();

  // add some plumbing here ...

  // and so on... 
})();

否则说:

  • 我将模块包装在函数内以避免污染
  • 类声明和类使用是交错的
  • 事件注册与其余代码交错
  • 模块全局变量在模块内部重用

现在我需要测试一下。 我认为问题主要在于事件注册和管道。

我的计划是将代码包装在函数中并导出我想要测试的每个函数和对象。代码如下所示:

var app = (function() {
  var app = {}

  // prepare some model
  var Query = BackboneModel.extend({});
  app.query = new Query();

  // register some events
  app.registerEvent = function() {
    $('body.something').click(function() {
      query.set('key', 'value');
      # ...
    });
  };
  app.registerEvent();  // XXX: call immediatly

  // create some backbone view
  app.QueryView = Backbone.View.extend({...})

  // init backbone view
  app.query.view = new QueryView();

  // add some plumbing here ...
  // wrapped in function with correct arguments and call it immediatly

  // and so on... 

  // ...
  return app;
})();

这是我第一次需要用 javascript 为此类应用程序编写测试,因此我想知道我使代码可测试的方法是否正确或可以改进。例如,在我看来,将事件注册包装在不带参数的函数中并立即调用它们似乎很愚蠢。

有没有 JavaScript 方法可以做到这一点?

最佳答案

因此,我找到了一种测试私有(private)函数的绝佳方法,同时保持生产代码的整洁。我不确定您是否使用 Grunt 或 Gulp 等构建系统,但如果您愿意,您可以执行以下操作:

//has a dependency of 'test' causing it to run testing suite first
gulp.task('js', ['test'], function() {
return gulp.src(source)
    .pipe(plumber())
    //create sourcemaps so console errors point to original file
    .pipe(sourcemaps.init())
    //strip out any code between comments
    .pipe(stripCode({
        start_comment: 'start-test',
        end_comment: 'end-test'
    }))
    //combine all separatefiles into one
    .pipe(concatenate('mimic.min.js'))
    //minify and mangle
    .pipe(uglify())
    .pipe(sourcemaps.write('maps'))
    .pipe(gulp.dest('dist/js'));
});

文件可能如下所示:

var app = (function () {
    function somePrivateFunction () {}
    function someotherPrivateFunction () {}

    var app = {
        publicFunction: function(){}
        publicVar: publicVar
    }

    /* start-test */
    app.test = {
        testableFunction: somePrivateFunction
    }
    /* end-test */
}());

测试运行后,测试注释之间的所有内容都会被删除,因此生产代码是干净的。 Grunt 有一个这样的版本,我认为任何自动化构建系统都可以做同样的事情。您甚至可以设置一个监视任务,以便它在每次保存时运行测试。否则,您必须在部署之前手动删除导出的测试对象。<​​/p>

对于 Backbone,只需将测试对象附加到模块并在测试中引用该对象。或者,如果您确实想将其分开,请将对象设置在全局范围内。 window.testObject = {//要测试的对象和方法列表... }; 并在部署之前删除该代码。

关于javascript - 组织中型 JavaScript 客户端应用程序的代码以进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34680453/

相关文章:

javascript - blueimp jquery-file-upload 如何检测按下取消按钮?

javascript - 以数组作为输入的递归函数

javascript - systemjs导入出错

javascript - 是否可以在引用索引的循环中调用 jQuery 中的变量

javascript - IE8 的 Google Maps API 问题

javascript - ajax 更新后 Jquery masonary 格式更改

javascript - Fancybox 2.1.5 点击时隐藏我的图像

backbone.js - 将 Backbone.ModelBinding 与 Backbone.Validation 一起使用

javascript - 主干 View 中的上下文

javascript - Yii + Backbone 获取数据