【问题标题】:Mocha async load a set of test case data and then dynamically create test casesMocha 异步加载一组测试用例数据,然后动态创建测试用例
【发布时间】:2019-11-14 04:52:46
【问题描述】:

我的问题:我想加载一组测试用例数据(不是测试用例本身),然后运行该组测试用例。所有操作,加载数据和正在测试的方法,都是异步的。


//testData.js
module.exports.loadTestData() {
    return new Promise(function(resolve, reject){
        var testDataArr = [];

        //do some async stuff and populate `testDataArr`
        setTimeout(1000, function(){
            testDataArr.push({
                "message": "test description 1",
                "data": "abcd" //data to pass to func
            })

            testDataArr.push({
                "message": "test description 1",
                "data": "abcd" //data to pass to func
            })

            resolve(testDataArr);
        })
    })
}

//myTests.test.js
const MyModule       = require('../index.js');
const TestDataHelper = require('./testData');
const chai           = require('chai');
const chaiAsPromised = require("chai-as-promised");

chai.use(chaiAsPromised);

const expect = chai.expect;

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            var failureCases;

            before(async function(){
                 failureCases = await TestDataHelper.getTestData();
            })

            it('load test data', function(done){
                //dummy test to cause the "before" to run and load test data
            })

            failureCases.forEach(function(case){
                it(case.message, async function(){
                    await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                })
            })
        })
    })
})

以上是我让它工作的最新尝试(即使用虚拟函数在forEach 之前加载异步测试数据),但我仍然收到以下错误:

TypeError: Cannot read property 'forEach' of undefined

这可能很明显,但我遇到了先有鸡还是先有蛋的问题,我不知道如何解决。因为describedoesn't support returned promises,所以我还没有找到一种方法,可以将测试数据异步加载到一个数组中,然后遍历该数组动态生成测试用例。

我尝试过的其他一些解决方法(包括使用--delay 标志):

//尝试的解决方法 #1(使用 --delay 标志)

var failureCases;

TestDataHelper.getTestData().then(function(arr){
    failureCases = arr;

    run();
})

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            failureCases.forEach(function(case){
                it(case.message, async function(){
                    await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                })
            })
        })
    })
})

//mocha --delay still produces "Cannot read property 'forEach' of undefined" error

尝试的解决方法 #2(在异步测试用例中加载数据,然后动态创建更多)

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            it('load test data', async function(done){
                var failureCases = await TestDataHelper.getTestData();

                failureCases.forEach(function(case){
                    it(case.message, async function(){
                        await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                    })
                })
            })
        })
    })
})

在这个解决方法中,mocha 不会产生错误,但它似乎并没有实际运行动态生成的测试,因为我只得到以下输出:

> mocha

#myTests
  #aFunction
    should fail
      load test data ✓

【问题讨论】:

    标签: node.js asynchronous mocha.js


    【解决方案1】:

    我知道这是一个有点老的问题,但不得不使用像 --delay 这样的选项似乎并不适合我,而且我在我的一个测试中遇到了同样的问题。我通过简单地将测试用例包装在自己的闭包中来开始工作。我认为以下内容适用于您的情况。

    describe('#myTests', function(){
        describe('#aFunction', function(){
            describe('should fail', function(){
                function itArray(case) {
                    it(case.message, async function(){
                        await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                    })
                }
                failureCases.forEach(function(case){
                   itArray(case);
                })
            })
        })
    })
    

    【讨论】:

      【解决方案2】:

      想通了。如果使用正确,使用--delay/run() 将起作用。 `describes 实际上需要在异步方法完成后在同一个块中执行。

      回到我的“尝试的解决方法 #1”,它应该如下所示:

      
      > mocha --delay
      
      //myTests.test.js
      TestDataHelper.getTestData().then(function(failureCases){
      
          describe('#myTests', function(){
              describe('#aFunction', function(){
                  describe('should fail', function(){
                      failureCases.forEach(function(case){
                          it(case.message, async function(){
                              await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                          })
                      })
                  })
              })
          })
      
          run();
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-26
        • 2012-08-22
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多