简体   繁体   English

为什么Mocha不执行.then语句中的测试?

[英]Why does Mocha not execute tests found in .then statements?

I'm working on a Protractor test suite using Mocha/Chai (and yes, I get the same problem in Jasmine). 我正在使用Mocha / Chai开发一个Protractor测试套件(是的,我在Jasmine中遇到了同样的问题)。

Because the app is rather complicated, I'd like to be able to dryly set up test suites that allow me to chain together operations into functions. 因为应用程序相当复杂,我希望能够干燥地设置测试套件,允许我将操作链接到功能中。 (Ie, "login, then browse to [parameterX], then browse to [parameterY], then expect first post title to be [parameterZ]). (即,“登录,然后浏览到[parameterX],然后浏览到[parameterY],然后期望第一个帖子标题为[parameterZ])。

But I seem to be having trouble with getting Mocha to run tests when I put them inside a .then() statement. 但是当我把它们放在.then()语句中时,我似乎遇到了让Mocha运行测试的麻烦。

Here's a small code snippet which shows the behavior I mean. 这是一个小代码片段,显示了我的意思。

var chai = require('chai');
var cAP = require('chai-as-promised')
chai.use(cAP);
const expect = chai.expect;

const doTest = (x) => {
  describe('main', function() {
    it('should return foo', function(done) {
      expect(x).to.equal('foo')
    })
  })
}

const wait = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve(), 10000)
})

wait()
  .then(() => doTest('foo'))

/* results in
 *   0 passing (4ms)
 */

describe and it blocks may not be done asynchronously. describe并且it可能不是异步完成的。 If you want to wait 10sec before your tests execute, you should use a before block, which supports async execution. 如果要在测试执行前等待10秒,则应使用支持异步执行的before块。 Your before callback takes one arg which is a done callback. before回调需要一个arg,这是一个done回调。 Inside this block you can wait 10sec and then call done. 在这个区块内,您可以等待10秒,然后调用完成。 All subsequent blocks will wait until done is called from within the before block. 所有后续块将等到done从内调用before块。

describe('your tests', () => {
    before(done => {
        setTimeout(done, 10000)
    })
    it('should return foo', () => {
        expect(x).to.equal('foo')
    })
})

The issue is that you are creating your test suite asynchronously. 问题是您正在异步创建测试套件。 By default Mocha does not allow creating a suite asynchronously. 默认情况下,Mocha不允许异步创建套件。 I took your code and made the following changes: 我拿了你的代码并进行了以下更改:

  1. Removed the done parameter from the callback passed to it because it is useless. 从传递给it的回调中删除了done参数,因为它没用。

  2. I added a call to run at the end of doTest . 我添加了一个在doTest结束时run的调用。

  3. I invoke Mocha with the --delay option: mocha --delay . 我使用--delay选项调用Mocha: mocha --delay

The --delay option will make Mocha wait for the test suite to be built. --delay选项将使Mocha等待构建测试套件。 You indicate that you are done building it by calling run() . 您通过调用run()表示已完成构建它。 Here's the full code with the changes mentioned above: 以下是上述更改的完整代码:

var chai = require('chai');
var cAP = require('chai-as-promised')
chai.use(cAP);
const expect = chai.expect;

const doTest = (x) => {
  describe('main', function() {
    it('should return foo', function() {
      expect(x).to.equal('foo')
    })
  })

  run();
}

const wait = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve(), 10000)
})

wait()
  .then(() => doTest('foo'))

chai-as-promised can make it a little bit cleaner chai-as-promise可以使它更清洁一点

/**
 * Modified by cool.blue on 26-Aug-16.
 */
'use strict';
var chai = require('chai');
var cAP = require('chai-as-promised');
chai.use(cAP);
const should = chai.should();

const wait5 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 5), 5000)
});

const wait10 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 10), 10000)
});

const doTest = (x, y, prep) => {
  describe('main', function() {
    this.timeout(15000);
    it('should return the right number for ' + x + ' and ' + y, function() {
      return prep(y).should.become(x)
    })
  })
};

[[17, 12, wait5], [15, 5, wait10], [15, 5, wait5]].forEach((listing) => doTest(...listing));

But, be careful of the arrow functions: they treat statements and expressions differently. 但是,要小心箭头函数:它们以不同的方式处理语句和表达式。

    it('should return the right number for ' + x + ' and ' + y,
      () => prep(y).should.become(x)
    )

is completely different from 完全不同于

it('should return the right number for ' + x + ' and ' + y, () => {
  prep(y).should.become(x)
})

but exactly the same as 但完全相同

it('should return the right number for ' + x + ' and ' + y, () => {
  return prep(y).should.become(x)
})

Arrow functions make me nervous, which is why I prefer... 箭头功能让我很紧张,这就是为什么我更喜欢...

it('should return the right number for ' + x + ' and ' + y, function() {
  return prep(y).should.become(x)
})

Well, I couldn't find an exact answer, but I was able to find something that kinda will work for what I really need this for, and so, here's what I did. 好吧,我找不到一个确切的答案,但我能找到一些对我真正需要的东西有用的东西,所以,这就是我的所作所为。

Essentially, all the other asynchronous actions I can pass in as a parameter to the testing function, and can use the before block's done() callback to make sure they are executed at the correct time. 本质上,我可以将所有其他异步操作作为参数传递给测试函数,并且可以使用before块的done()回调来确保它们在正确的时间执行。

const wait5 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 5), 5000)
})

const wait10 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 10), 10000)
})

const doTest = (x, y, prep) => {
  describe('main', function() {
    let z;
    before(function (done) {
      this.timeout(30000);
      prep(y).then((val) => {
        z = val;
        done();
      })
    })
    it('should return the right number for ' + x + ' and ' + y, () => {
      expect(x).to.equal(z)
    })
  })
}

[[17, 12, wait5], [15, 5, wait10], [15, 5, wait5]].forEach((listing) => doTest(...listing))


/* Result: 

  main
    √ should return the right number for 17 and 12

  main
    √ should return the right number for 15 and 5

  main
    1) should return the right number for 15 and 5


  2 passing (20s)
  1 failing

  1) main should return the right number for 15 and 5:

      AssertionError: expected 15 to equal 10
      + expected - actual

      -15
      +10
 */

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

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