我该如何进行异步单元测试?

5

我正在使用pg-promise。作为一个学习者,如果这似乎微不足道,请原谅。我该如何编写单元测试?它报错说数据未定义。我一直在JS文件中建立连接并导出该模块。另一个JS文件用于对数据库进行查询并获取结果集。代码按预期工作,但有问题,我该如何使用Mocha和Chai编写单元测试。

test1.js
var dbConn= pgp(connUrl);
module.exports = {
    getconnect: function () {
        return dbConn;
    }
};

test2.js

module.exports = {
    getData: function (req, res) {
      db.getconnect().query(sqlStr, true)
                .then(function (data) {  
                    console.log("DATA:", data);
                    return data; 
                  } } }

unittest.js

describe("Test Cases", function (done) {

    it('retrieve response', function (done) {
        var req = {};
        var res = {};
        test2.getData(req, res);    
        // how would i retrieve value of data from test2.js so i can test
        done();
    });
});

我该如何从test2.js中检索“data”值并在unittest.js中使用?
(请注意,此处只是翻译,不包括HTML标签)

@vitaly-t.,您能否建议我如何编写单元测试? - aka
你应该问的正确问题是如何为异步库编写测试。这与pg-promise没有太大关系。同时,你可以查看pg-promise测试作为示例,了解库是如何进行自我测试的。 - vitaly-t
很奇怪你有一个异步函数,只记录输出但不做其他任何事情。如果标准输出的输出是重要的,则测试它,而不是测试该函数,因为该函数不返回任何内容,这使其无法测试。我个人会将特定的测试编写为bash脚本,因为那是最简单的方法。如果你必须用js编写它,那么就像编写bash脚本一样编写它:执行脚本并grep它的标准输出。 - slebetman
@slebetman 我想测试值“data”。我不知道如何将“data”的值返回到unitest.js。 - aka
一个很好的实际例子:使用pg-promise在Mocha测试之间清理数据库 - vitaly-t
2个回答

5

您的getData函数必须返回一个Promise对象。客户端代码将能够识别它何时完成(已解决)。

module.exports = {
    getData: function (req, res) {
      return db.getconnect().query(sqlStr, true)
                .then(function (data) {  
                    console.log("DATA:", data);
                    return data; 
                  } } }

测试:

describe("Test Cases", function () {
    it('retrieve response', function (done) {
        var req = {};
        var res = {};
        test2.getData(req, res).then(function(data){
          // test of data returned
          done(); // finish test
        }).catch(done);// report about error happened
    });
});

如果您的模块不需要对数据进行任何处理,则可以删除整个.then部分而不会影响功能。
但是,如果您想预处理数据,请不要忘记从每个链接的.then返回它。

如果您的测试库需要异步存根,可以使用async/await功能来处理它。

it('retrieve response', async function(){
  try {
    var data = await test2.getData(req, res);
    // test data here
  } catch (e) {
    // trigger test failed here
  }
});

或者进行桩测试,类似这样:
var dbStub = sinon.stub(db, 'getConnect');
dbStub.yields(null, {query: function(){/*...*/}});

如果你的 node.js 版本支持 async/await,你可以使用它。已添加到答案中。 - vp_arth

-1
如果您的函数返回一个 Promise,那么您可以在测试中使用 await
describe("Test Cases", function (done) {
    it('retrieve response', async function (done) {
        try {
          var data = await test2.getData();
          // check data constraints ...
          ...
        } catch(err) {
          ... 
        }
        done(); // finish test
    });
});   

它报错了,类似于缺少“)”。我检查了所有地方,没有漏掉任何括号。 - aka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接