【问题标题】:Mocha 'this' in before and beforeEach hooks在 before 和 beforeEach 中的 Mocha 'this' 钩子
【发布时间】:2014-12-08 12:44:13
【问题描述】:

以下使用Mocha.js 编写的测试代码失败。我希望 someVal 在最后一次测试中增加 3 倍并等于 3。这个问题出现在更复杂的场景中,我使用外部 before 块中设置的值在内部 beforeEach 块中设置另一个值。简化案例:

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);
    });
  });
});

【问题讨论】:

    标签: javascript mocha.js


    【解决方案1】:

    说明

    我不知道有 任何 版本的 Mocha 可以运行您在问题中显示的代码而不会出错。为了使您的代码正常工作,它必须像这样编写:

    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);
            });
        });
    });
    

    在传递给describe 的函数和传递给describe 块(beforebeforeAll 等)的钩子的函数内部,this 的值是一个“上下文”对象,它是describe 及其所有 自己的 钩子(不是嵌套在其中的 other describe 调用的钩子)也是如此。因此,当您分配给this 时,它会分配给 context。如果您想在对 describe 的嵌套调用中或在测试中访问此上下文,您必须向上遍历 describe 并测试对象。

    解决方案

    我会按照 Second Rikudo 建议的方式来做这件事:使用一个范围为您最上面的 describe 调用的变量。为了完整起见:

    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);
            });
        });
    });
    

    【讨论】:

    【解决方案2】:

    this 不是你想象的那样。 this 在每个 function() {} 块中都被重新定义(除非 Mocha 以我不熟悉的某种特定方式调用它们)。

    你想要的是利用作用域来发挥你的优势:

    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);
        });
      });
    });
    

    另外,你不需要return 这么多。事实上,您几乎不必在测试代码中返回。

    【讨论】:

    • 我主要用咖啡脚本写作。这是编译器的输出,经过一些小的修改。当我手动编写 JS 时,我不会返回太多 :)
    • 我描述的行为在版本 1.18.2 中起作用,但在 1.19.0 中发生了变化(在合并 github.com/mochajs/mocha/pull/1164/files 之后)。现在我正在考虑是否或如何让 Mocha 表现得像以前一样。
    猜你喜欢
    • 2017-10-10
    • 1970-01-01
    • 2019-10-14
    • 2016-08-13
    • 1970-01-01
    • 2019-11-02
    • 2019-08-11
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多