摩卡测试用例会在诺言获得数据之前执行

时间:2018-11-30 17:47:27

标签: node.js mocha

在promise获取数据之前执行测试用例(Test1,Test2)。这是文件mockExecution.js

describe('AC 1: This is suite one', ()=>
{
    before((done)=>
    {
        promiseResp.then((data) => {
            console.log("i am in the promise");
            responseData = data;
            process.exit(0);
        }, (err) => {
            console.log('promiseResp.err', err);
            process.exit(1);
        })
        done();
    })
    it('Test1', (done)=>
    {
        expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
        done();
    });

    it('Test2', (done)=>
    {

        expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
        done();
    });

});

Before块中的PromiseResp不执行。因此,“ responseData”变量没有数据,因此抛出测试用例失败。我猜这里有一些异步时间问题,但是不知道如何解决它,我也把这个“ process.exit(0)”放在哪里。下面是实际输出:

AC 1: This is suite one
I am in the before
    1) Test1
    2) Test2


  0 passing (7ms)
  2 failing

  1) AC 1: This is suite one
       Test1:
     TypeError: Cannot read property 'measure' of undefined
      at Context.it (QA/mockExecution.js:160:29)

  2) AC 1: This is suite one
       Test2:
     TypeError: Cannot read property 'measure' of undefined
      at Context.it (QA/mockExecution.js:167:29)

[process business logic and prints some logs here, i can't paste here]
finished analyzing all records
i am in the promise
npm ERR! Test failed.  See above for more details.

我期望按照以下顺序输出:

[process business logic and prints some logs here, I can't paste here]
finished analyzing all records
AC 1: This is suite one
    I am in the before
       I am in the promise
        1) Test1 passed
        2) Test2 paseed

3 个答案:

答案 0 :(得分:2)

您需要在您的done之内致电then 分配了responseData = data

before((done) => {
  promiseResp.then((data) => {
    responseData = data;
    // Promise has resolved. Calling `done` to proceed to the `it` tests.
    done();
  })
  .catch((err) => {
    // Calling `done` with a truthy `err` argument, in case
    // the promise fails/rejects, to fail-early the test suite.
    done(err);
  })
})

否则,before会过早结束并继续进行下一个测试,直到Promise实际解析并分配您的responseData变量为止。

以下是使用before钩子的工作示例:

const expect = require('chai').expect

const getFooValue = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('foo')
    }, 500)
  })
}

describe('#getFooValue()', function () {
  let responseData

  before(done => {
    getFooValue().then(data => {
      responseData = data
      done()
    })
    .catch(err => {
      done(err)
    })
  })

  it('response has a value of foo', () => {
    expect(responseData).to.equal('foo');
  })

  it('response is a String', () => {
    expect(responseData).to.be.a('String');
  })
})

您现在正在做的是:

  • 您定义了Promise
  • 您(过早)致电done,然后Mocha继续执行it测试。
  • it仍在responseData时运行undefined测试。
  • Promise中的before最终解析并分配了responseData变量。

...但是那时为时已晚。测试已经运行。

答案 1 :(得分:2)

done与promises一起使用是一种反模式,因为像在这种情况下,这通常会导致错误的控制流。所有主要的测试框架都已经支持了承诺,包括Mocha。

如果默认超时(2秒)不足以解决承诺,则应增加超时值,例如如this answer所述,方法是将其设置为当前测试套件(在this上下文中为describe)。请注意,箭头功能应替换为常规功能以达到套件上下文。

应该是:

describe('AC 1: This is suite one', function () {
    this.timeout(60000);

    before(() => {
        return promiseResp.then((data) => {
            responseData = data;
        });
    });

    it('Test1', () => {            
       expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
    });
    ...

不需要catch来保证;承诺拒绝将由框架处理。测试中不需要done;它们是同步的。

答案 2 :(得分:1)

您的it()中没有任何保证,因此没有必要执行done(),但应在then()内部调用它,因为它是回调。

总的来说,使用异步/等待更干净。不过,它在before()中效果不佳。

在describe()中最好使用'function()'来设置测试的超时时间(将其作为一种链式方法调用,这在我的经验中是行不通的)

bundle