为什么期望setTimeout中的语句不能运行

时间:2017-08-22 15:13:56

标签: javascript mocha settimeout sinon

我的代码:

  before(function _before(){
    this.spyLog = sinon.spy(this.myOBJ.log, 'warn');
  });

  after(function _after(){
    this.spyLog.restore();
  });

  it('should', sinon.test(function() {
    const stubFindOne = this.stub(this.myOBJ, 'findOne');
    stubFindOne.returns(bluebird.reject(new Error('Should have failed')));
    this.myOBJ.toBeTestedFunction({});
    setTimeout(function _expect() {
      console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++');
      console.log('this.spyLog', this.spyLog.args);
      expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed');
      console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++');
    }, 100);
  }));

为什么_expect功能无法运行?感谢

更新 尝试了以下代码,但获得了Error: timeout of 2000ms exceeded。我认为这是因为没有调用done。我需要this.myOBJ.toBeTestedFunction({});完成运行然后运行期望。如何修复代码?

  it('should', sinon.test(function(done) {
    const stubFindOne = this.stub(this.myOBJ, 'findOne');
    stubFindOne.returns(bluebird.reject(new Error('Should have failed')));
    this.myOBJ.toBeTestedFunction({});
    setTimeout(function _expect() {
      console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++');
      console.log('this.spyLog', this.spyLog.args);
      expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed');
      console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++');
          done();
    }, 100);
  }));

更新

我的以下代码有效。但是如何改进呢?

  it('should', sinon.test(function() {
    const stubFindOne = this.stub(this.myOBJ, 'findOne');
    stubFindOne.returns(bluebird.reject(new Error('Should have failed')));
    return new bluebird.Promise((resolve, reject) => { 
      this.myOBJ.tobetestedFunction();
      resolve();
    })
    .delay(1000)
    .then(() => {
      expect(this.spyLog.args[2][0].toString()).to.be.equal('Error: Should have failed');
    });
  }));

1 个答案:

答案 0 :(得分:1)

如上所述,在任何异步代码(例如回调到setTimeout)可以运行之前,测试用例已经结束。在done来电中添加it参数,并在done()回调结束时致电setTimeout

那就是说,我想我会回过头来整理一下我所说的代码示例,这让我更接近你的代码...这看起来像是最终会给你带来麻烦。看起来您正在预测一些异步事件以使您的期望符合预期,而不是控制执行这些事件只是说"呃,它们应该在100个刻度内完成......"这不是一个好计划。

那个说,它看起来像

it('should', sinon.test(function(done) {
    const stubFindOne = this.stub(this.myOBJ, 'findOne');
    stubFindOne.returns(bluebird.reject(new Error('Should have failed')));
    this.myOBJ.toBeTestedFunction({});
    setTimeout(function _expect() {
      console.log('++++++++++++ 1 ++++++++++++++++++++++++++++++++++++++++');
      console.log('this.spyLog', this.spyLog.args);
      expect(this.spyLog.args[0][0].toString()).to.be.equal('Error: Should have failed');
      console.log('++++++++++++ 2 ++++++++++++++++++++++++++++++++++++++++');
      done();
    }, 100);
  }));

更新 - 您提到添加done无法正常工作(超时错误);这几乎可以肯定是因为你的功能所附带的sinon.test封装器正在妨碍你。我不熟悉sinon(并且快速谷歌没有提供test方法的文档),但一般来说,您需要的是{{1}返回的函数}到(1)取一个sinone.test参数,(2)将它作为第一个参数传递给它包装的回调。在您的函数中放置done参数显然不会发生这种情况。您必须咨询done文档。 (您尝试使用的茉莉花功能是"异步测试",但由于sinon试图与框架无关,我不确定他们是否/如何解决此问题。也许只是关于需要额外参数的测试方法?)

关于为什么这不是一个好的测试方法的后续问题:对未在实时计算环境中编码的事件实施实时约束绝不是一个好主意。如果要满足条件需要250个滴答,那真的是测试失败吗?如果是这样,你要测试性能 - 而不是功能 - 即便如此,你所拥有的是一个可以传递某些硬件并在其他硬件上失败的测试,或者测试"某些时间"。 ..不是你想要的自动化测试套件的行为。

此外,您正在等待的异步事件几乎肯定是在您的测试所依赖的行为之外的代码 - 在这种情况下,它不是适当的单元测试。

做这种测试"正确的方式"显然更加困难,因为你会嘲笑外部依赖关系并使用模拟的响应推进你的测试以评估期望