简体   繁体   English

Mocha'this'在之前和之前都是钩子

[英]Mocha 'this' in before and beforeEach hooks

The following test code, written using Mocha.js fails. 使用Mocha.js编写的以下测试代码失败。 I expect the someVal to be increased 3 times and equal 3 in the last test. 我希望someVal在最后一次测试中增加3倍并且等于3。 The issue came up in more complex scenario where I used value set in outer before block to set up another in inner beforeEach block. 这个问题出现在更复杂的场景中,我使用外部块之前的值设置在内部beforeEach块中设置另一个。 Simplified case: 简化案例:

describe('increasing 3 times', function() {
  before(function() {
    this.instanceThis = this;
    return this.someVal = 0;
  });
  beforeEach(function() {
    return this.someVal += 1;
  });
  return describe('going deeper', function() {
    before(function() {
      return this.someVal += 1;
    });
    beforeEach(function() {
      return this.someVal += 1;
    });
    return it('has increased someVal to 3', function() {
      return this.someVal.should.equal(3);
    });
  });
});

Explanation 说明

I don't know of any version of Mocha that would run the code you show in your question without error. 我不知道任何版本的Mocha会运行您在问题中显示的代码而不会出错。 For your code to work, it would have to be written like this: 为了让你的代码工作,它必须像这样写:

require("chai").should();

describe('increasing 3 times', function() {
    before(function() {
        this.someVal = 0;
    });
    beforeEach(function() {
        this.someVal += 1;
    });
    describe('going deeper', function() {
        var parent_ctx = this.parent.ctx;
        before(function() {
            parent_ctx.someVal += 1;
            // The line above is equivalent to this:
            // this.test.parent.ctx.someVal += 1;
        });
        beforeEach(function() {
            parent_ctx.someVal += 1;
        });
        it('has increased someVal to 3', function() {
            parent_ctx.someVal.should.equal(3);
            // The above line is equivalent to this:
            // this.test.parent.parent.ctx.someVal.should.equal(3);
        });
    });
});

Inside the function passed to describe and the functions passed to the hooks of a describe block ( before , beforeAll , etc.) the value of this is a "context" object which is the same for the describe and all of its own hooks (not the hooks of other describe calls nested in it). 内传递给函数的describe和传递到的钩子的功能describe块( beforebeforeAll等)的值this是一个“上下文”对象,它是相同的describe和所有它自己的挂钩(未嵌套在其中的其他 describe调用的钩子)。 So when you assign to this , it assigns to the context . 因此,当您分配给this ,它会分配给上下文 If you want to access this context inside nested calls to describe or in tests you have to walk up the tree of describe and test objects. 如果要在嵌套调用中访问此上下文以进行describe或在测试中,您必须走上describe和测试对象的树。

Solution

I would do it exactly the same way Second Rikudo suggested: use a variable scoped to your uppermost describe call. 我会按照第二个Rikudo建议的方式完成相同的操作:使用一个作用于最上层describe调用的变量。 For the sake of completeness: 为了完整起见:

require("chai").should();

describe('increasing 3 times', function() {
    var someVal;
    before(function() {
        someVal = 0;
    });
    beforeEach(function() {
        someVal += 1;
    });
    describe('going deeper', function() {
        before(function() {
            someVal += 1;
        });
        beforeEach(function() {
            someVal += 1;
        });
        it('has increased someVal to 3', function() {
            someVal.should.equal(3);
        });
    });
});

this is not what you think it is. this不是你的想法。 this gets redefined in every function() {} block (unless Mocha calls them in some specific way I'm not familiar with). this会在每个function() {}块中重新定义(除非Mocha以某种我不熟悉的特定方式调用它们)。

What you want is to use scope in your advantage: 你想要的是使用范围有利于你:

describe('increasing 3 times', function() {
  var someVal; // Initialization.
  before(function() {
    someVal = 0; //No need to return from before()
  });
  beforeEach(function() {
    someVal += 1;
  });
  describe('going deeper', function() {
    before(function() {
      someVal += 1;
    });
    beforeEach(function() {
      someVal += 1;
    });
    return it('has increased someVal to 3', function() {
      someVal.should.equal(3);
    });
  });
});

Also, you don't need to return so much. 此外,您不需要return那么多。 In fact, you almost never have to return in test code. 实际上,您几乎不必返回测试代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM