Jasmine的beforeEach是同步的吗?

时间:2015-07-18 14:59:17

标签: javascript jasmine

如果您有多个beforeEach,它们会一个接一个地运行吗?

beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});

似乎他们会。我尝试用我的代码测试它:

describe('Directive: Statement', function() {
  var el, scope, statements;

  beforeEach(module('simulatedSelves'));
  beforeEach(module('templates'));
  beforeEach(inject(function($compile, $rootScope) {
    console.log(1);
    scope = $rootScope.$new();

    statements = [];
    scope.statement = {
      text: 'test',
      arr: []
    };
    scope.statement.parent = statements;
    statements.push(scope.statement);

    el = angular.element('<statement statement=statement></statement>');
    $compile(el)(scope);
    scope.$digest();
  }));
  beforeEach(function() {
    var counter = 0;
    console.log(2);
    for (var i = 0; i < 1000000; i++) {
      counter++;
    }
    console.log(counter);
  });
  beforeEach(function() {
    console.log(3);
  });

  it('test statement has correct properties', function() {
    // stuff
  });
});

记录:

1
2
1000000
3

由于带有beforeEach循环的for在记录3之前记录其内容,我认为beforeEach同步运行。这是真的吗?

1 个答案:

答案 0 :(得分:8)

是的,所有beforeEach都将按您定义的顺序执行。

如果你钻进Jasmine,你最终会进入this definition

Suite.prototype.beforeEach = function(fn) {
  this.beforeFns.unshift(fn);
};

当您添加describe时,Suite生成并嵌套。每个Suite都会使用this.beforeFns = []初始化,如您所见,该unshift已添加到beforeEach。请注意,beforeEach会添加到数组的左侧,因此您需要先运行后面定义的var beforeAndAfterFns = function(suite) { return function() { var befores = [], afters = []; while(suite) { befores = befores.concat(suite.beforeFns); afters = afters.concat(suite.afterFns); suite = suite.parentSuite; } return { befores: befores.reverse(), afters: afters }; }; }; 。当Jasmine走进儿童套房的父母时,那是fixed later,收集所有beforeEach个列表,然后将它们反转为按照您想要的顺序运行。

beforeEach

作为Dan points out,我们到目前为止假设您的所有beforeEach(function(done) { setTimeout(function() { console.log('Async'); done(); }, 1000) }); 都是同步的。从Jasmine 2开始,您可以像这样设置异步done

for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
  var queueableFn = queueableFns[iterativeIndex];
  if (queueableFn.fn.length > 0) {
    attemptAsync(queueableFn);
    return;
  } else {
    attemptSync(queueableFn);
  }
}

在运行时,Jasmine会向您发送attemptAsync函数并以异步if your function takes an argument执行。 (Function.length返回函数期望的参数数量。

done()

QueueRunner等待您在beforeEach移至下一个describe('beforeEach', function() { var data = null; beforeEach(function() { data = []; }); beforeEach(function() { data.push(1); }); beforeEach(function(done) { setTimeout(function() { data.push('Async'); done(); }, 1000); }); beforeEach(function() { data.push(2); }); beforeEach(function() { data.push(3); }); it('runs in order', function(){ expect(data).toEqual([1, 'Async', 2, 3]); }); }); 挂钩之前致电textBox_Leave,因此订购仍然有效!非常整洁。

ActiveControl