Sql server nodejsmssql和承诺混淆

Sql server nodejsmssql和承诺混淆,sql-server,node.js,promise,sinon,Sql Server,Node.js,Promise,Sinon,我对javascript中的承诺非常陌生,所以这个问题是为了帮助我弄清楚为什么使用承诺会出现错误(顺序很奇怪)。除此之外,我第一次忙于使用ms sql repo、sinonjs和restify,所以这也没什么帮助 这个问题与我之前问的一个问题有关 在上面的问题中,我需要删除SQL DB,这是我在@robertklep的帮助下成功完成的。然而,作为一个健全性检查,我想检查端点是否仍然像以前一样返回我期望的数据,所以我取消了存根。现在我得到以下错误,我不知道为什么: [错误:发送邮件后无法设置邮件头

我对javascript中的承诺非常陌生,所以这个问题是为了帮助我弄清楚为什么使用承诺会出现错误(顺序很奇怪)。除此之外,我第一次忙于使用ms sql repo、sinonjs和restify,所以这也没什么帮助

这个问题与我之前问的一个问题有关

在上面的问题中,我需要删除SQL DB,这是我在@robertklep的帮助下成功完成的。然而,作为一个健全性检查,我想检查端点是否仍然像以前一样返回我期望的数据,所以我取消了存根。现在我得到以下错误,我不知道为什么:

[错误:发送邮件后无法设置邮件头。]

测试:

端点:

var select = require('../helpers/data_access/select'),
    read_file = require('../helpers/read_file'),
    format = require('string-format');

const db_config_name = 'db.goaml';

module.exports = function (server) {

    server.get('/api/v1/account_types', function (req, res, next) {
        var query = read_file.get_file_contents('path to query');

        select.query_list(db_config_name, query, function (err, records) {
            console.log('test 1');
            if (err != null) {
                return next(err);
            }
            res.send(records);
            //return next(); <-- EDIT: Removed as per Mike Perrenoud answer
        });

        //return next(); <-- EDIT: Removed as per Mike Perrenoud answer
    });

    server.get('/api/v1/account_type/:id', function (req, res, next) {
        var query =
            format(read_file.get_file_contents('path to query'), req.params.id);

        select.query_single(db_config_name, query, function (err, records) {
            console.log('test 2');
            if (err != null) {
                return next(err);
            }
            res.send(records[0]);
            //return next(); <-- EDIT: Removed as per Mike Perrenoud answer
        });

        //return next(); <-- EDIT: Removed as per Mike Perrenoud answer
    });

    server.post('/api/v1/account_type', function (req, res, next) {
        res.send({'result': 'post account_type : ' + req.body.id});
        return next();
    });

    server.put('/api/v1/account_type', function (req, res, next) {
        res.send({'result': 'put account_type : ' + req.body.id});
        return next();
    });

    server.del('/api/v1/account_type/:id', function (req, res, next) {
        res.send({'result': 'delete account_type : ' + req.params.id});
        return next();
    });

};
当我运行gulp任务来测试上述代码时,我得到以下输出:

C:\Code\JS\general_admin_service>gulp test
[16:12:47] Using gulpfile C:\Code\JS\general_admin_service\gulpfile.js
[16:12:47] Starting 'test'...
[16:12:47] Finished 'test' after 62 ms


  /account_types
    1) GET 200 List
    2) GET 200 Single
test 3
test 1
test 4
[Error: Can't set headers after they are sent.]
test 1
    √ POST 200 Single
test 3
test 2
test 4
[Error: Can't remove headers after they are sent.]
test 2
    √ PUT 200 Single
    √ DELETE 200 Single


  3 passing (400ms)
  2 failing

  1) /account_types GET 200 List:
     Error: expected 200 "OK", got 500 "Internal Server Error"
      at Test._assertStatus (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:232:12)
      at Test._assertFunction (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:247:11)
      at Test.assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:148:18)
      at assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:127:12)
      at C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:124:5
      at Test.Request.callback (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:831:3)
      at Stream.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:1049:12)
      at Unzip.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\utils.js:108:12)

  2) /account_types GET 200 Single:
     Error: expected 200 "OK", got 500 "Internal Server Error"
      at Test._assertStatus (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:232:12)
      at Test._assertFunction (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:247:11)
      at Test.assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:148:18)
      at assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:127:12)
      at C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:124:5
      at Test.Request.callback (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:831:3)
      at Stream.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:1049:12)
      at Unzip.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\utils.js:108:12)




events.js:142
      throw er; // Unhandled 'error' event
      ^
 Error: 2 tests failed.
C:\code\JS\general\u admin\u service>gulp测试
[16:12:47]使用gulpfile C:\Code\JS\general\u admin\u service\gulpfile.JS
[16:12:47]开始“测试”。。。
[16:12:47]62毫秒后完成“测试”
/帐户类型
1) 获取200个列表
2) 单程200
测试3
测试1
测试4
[错误:发送邮件后无法设置邮件头。]
测试1
√ 邮政200单
测试3
测试2
测试4
[错误:发送邮件后无法删除邮件头。]
测试2
√ 单打200分
√ 删除200单
3次通过(400ms)
2失败
1) /account\u类型获取200个列表:
错误:预期200“正常”,得到500“内部服务器错误”
测试时。\u资产状态(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:232:12)
at Test.\u assertFunction(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:247:11)
在Test.assert(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:148:18)
在断言(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\test.JS:127:12)
在C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\test.JS:124:5
在Test.Request.callback(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\index.JS:831:3)
在溪流中。(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\index.JS:1049:12)
在解压时。(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\utils.JS:108:12)
2) /account\u类型获得200个单张:
错误:预期200“正常”,得到500“内部服务器错误”
测试时。\u资产状态(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:232:12)
at Test.\u assertFunction(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:247:11)
在Test.assert(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\Test.JS:148:18)
在断言(C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\test.JS:127:12)
在C:\Code\JS\general\u admin\u service\node\u modules\supertest\lib\test.JS:124:5
在Test.Request.callback(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\index.JS:831:3)
在溪流中。(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\index.JS:1049:12)
在解压时。(C:\Code\JS\general\u admin\u service\node\u modules\superagent\lib\node\utils.JS:108:12)
events.js:142
投掷者;//未处理的“错误”事件
^
错误:2个测试失败。
让我感到困惑的是,如果我查看
控制台.log的
输出,很明显代码进入了
sql.request的
块,然后调用回调。我可以确认,如果我添加一个
console.log
来检查records参数的值,实际上有数据返回其中

此时,
res.send
get被命中,但是在
sql.query
catch
块中捕获到一个错误,此时出现混淆:

如果有成功的回报,为什么会被击中

代码的哪一部分响应测试。也就是说,设置标题后为什么要更改标题?(下一个(错误)
可能与此有关吗?)

如前所述,这个问题与我的前一个问题有很大关系。我必须对代码进行修改,以满足我的单元测试。但是,我觉得有必要进行健全性检查,确保数据仍按预期返回,在这一点上,我认为ms sql使用的Promise框架阻碍了向测试返回值。(我不是在质疑承诺框架的价值)

我希望有人知道我做错了什么

编辑:

所以我有点困惑到底发生了什么。就代码本身而言,如果我在测试的
部分之前取消注释
,在
部分之后取消注释
,测试就会失败,看起来这与回调有关

如果我完全删除回调,并在
sql.Request的
中返回
,然后在
捕获中返回
抛出err
,则测试通过


但是,如果我在没有存根的情况下进行直接测试,此设置将不会返回值。

发生这种情况是因为您正在执行
return next()之前,SQL Server的回调已完成。这是一个问题的原因是,虽然本质上是异步的,但总体上执行的是一组同步操作

正在发生的是
res.send(记录)失败,因为已调用
next()
,并且服务器已返回
200


最后,您不需要
returnnext()res.send(记录)后的code>因为
res.send(记录)结束进程并返回响应。

你说的话很有道理,我已经删除了
return next()-首先是回调内部的,然后是回调外部的。然而,不管我用哪种方式,我仍然得到相同的读数。r
var sql = require('mssql'),
    config = require('./configs/config');

module.exports = {
    query_list: function (config_name, sql_query, callback) {
        return query(config_name, sql_query, true, callback);
    },
    query_single: function (config_name, sql_query, callback) {
        return query(config_name, sql_query, false, callback);
    }
};

function query(config_name, sql_query, isList, callback) {
    var db_config = config.get(config_name),
        connection = new sql.Connection(db_config);

    connection.connect(function () {
        new sql.Request(connection)
            .query(sql_query)
            .then(function (records) {
                console.log('test 3');
                callback(null, isList ? records : records[0]);
                connection.close();
            })
            .catch(function (err) {
                console.log('test 4');
                console.log(err);
                callback(err, null);
            });
    });

    // EDIT for answer:
    // This catch is not allowed. IE the connection isn't a promise. Thus
    // when the code responded with something valid, it reached this part
    // after that and realised this is an illegal statement. As a result
    // it throws an error after the res.send was already hit and showing the
    // initial error I reported.
    // .catch(function (err) {
    //     console.log('test 5');
    //     callback(err, null);
    //  });
}
C:\Code\JS\general_admin_service>gulp test
[16:12:47] Using gulpfile C:\Code\JS\general_admin_service\gulpfile.js
[16:12:47] Starting 'test'...
[16:12:47] Finished 'test' after 62 ms


  /account_types
    1) GET 200 List
    2) GET 200 Single
test 3
test 1
test 4
[Error: Can't set headers after they are sent.]
test 1
    √ POST 200 Single
test 3
test 2
test 4
[Error: Can't remove headers after they are sent.]
test 2
    √ PUT 200 Single
    √ DELETE 200 Single


  3 passing (400ms)
  2 failing

  1) /account_types GET 200 List:
     Error: expected 200 "OK", got 500 "Internal Server Error"
      at Test._assertStatus (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:232:12)
      at Test._assertFunction (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:247:11)
      at Test.assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:148:18)
      at assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:127:12)
      at C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:124:5
      at Test.Request.callback (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:831:3)
      at Stream.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:1049:12)
      at Unzip.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\utils.js:108:12)

  2) /account_types GET 200 Single:
     Error: expected 200 "OK", got 500 "Internal Server Error"
      at Test._assertStatus (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:232:12)
      at Test._assertFunction (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:247:11)
      at Test.assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:148:18)
      at assert (C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:127:12)
      at C:\Code\JS\general_admin_service\node_modules\supertest\lib\test.js:124:5
      at Test.Request.callback (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:831:3)
      at Stream.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\index.js:1049:12)
      at Unzip.<anonymous> (C:\Code\JS\general_admin_service\node_modules\superagent\lib\node\utils.js:108:12)




events.js:142
      throw er; // Unhandled 'error' event
      ^
 Error: 2 tests failed.