2016-07-28 4 views
1

Использование библиотеки node-mssql для извлечения данных из SQL. Я использовал Синон какое-то время (написано около 200 тестов); с тонны проблем, ломающих голову о том, как заглушить эту библиотеку. Код выглядит так:Как использовать Sinon для взаимодействия с базой данных с помощью библиотеки mssql?

var sql = require('mssql'); 
var conn = new sql.Connection(sqlConfig); // sqlConfig is connection info, defined elsewhere 

conn.connect(function(err) { 
    var req, selectFromTable; 
    if (err != null) { 
    // handle error 
    } 
    req = new sql.Request(conn); 
    selectFromTable = "select * from DW." + table + " where DWCreatedDate >= '" + start + "' and DWCreatedDate <= '" + end + "' "; 
    logger.debug("Selecting with: ", selectFromTable); 
    req.input('statement', sql.NVarChar, selectFromTable); 
    return req.execute('sp_executesql', function(err, results, returnValue, affected) { 
    if (err != null) { 
     // etc. 
    } else { 
     // data processing 
    } 
    }); 
}); 

Код работает нормально. Теперь я пытаюсь написать для этого тест. Я знал, что эту библиотеку будет трудно проверить, поэтому я откладывал. Мой самый близкий код:

var conn, reqExecute, sqlReqStub; 
sqlReqStub = sinon.stub(); 
sqlReqStub.execute = sinon.stub(); 
sinon.stub(sql, 'Request').returns(sqlReqStub); 
conn = sinon.stub(); 
sinon.stub(sql, 'Connection').returns(conn); 

conn.connect = sinon.stub().callsArgWith(0, null); 

reqExecute = sqlReqStub.execute.withArgs('sp_executesql').onFirstCall().callsArgWith(1, null, { 
    a: 1 
}); 

Ваш естественный наклон может быть, чтобы сказать «хорошо, использовать createStubInstance», но когда я использую, что я вернусь объекты связи (new sql.Connection(config)), которые имеют TediousRequest (что библиотека по умолчанию, когда он строит из объект драйвера внутри соединения) в них вместо моего запроса на заглушку. Я не могу найти TediousRequest в любом месте объекта sql, чтобы его заглушить.

Я застрял здесь; надеясь, что у кого-то есть код, который делает это или может объяснить, что я делаю неправильно.

ответ

0

Ну, мне удалось решить проблему, но по какой-то причине она немного взломана. Возможно потому, что я никогда не понял, как заглушить звонок new sql.Request(conn).

Идеально Я бы хотел, чтобы эта работа не включалась в библиотеку sql в моем module.exports. Я могу сделать это с библиотекой request, но через несколько часов, отбиваясь от этой библиотеки, я не могу заставить ее работать так же.

Во-первых: экспорт библиотеки SQL:

sql = require('mssql') 
// much code 
module.exports.sqlLib = sql 

Второе: тупиковые вещи:

var connection, sqlReqStub, sqlStubLib; 
    var server = require('./index.js')  
    sqlStubLib = {};  
    connection = new EventEmitter();  
    connection.connected = true;  
    connection.close = function() {};  
    connection.connect = sinon.stub().callsArgWith(0, null);  
    sqlStubLib.Connect = sinon.stub();  
    sqlStubLib.Connection = function() { 
    return connection; 
    };  
    sqlReqStub = sinon.stub();  
    sqlReqStub.input = function() {};  
    sqlReqStub.execute = sinon.stub();  
    sqlReqStub.execute.withArgs('sp_executesql').onFirstCall().callsArgWith(1, null, [ 
    [ 
    // js object 
    ] 
    ], null, null); 

    sqlStubLib.Request = function() { 
    return sqlReqStub; 
    }; 

    server.sqlLib = sqlStubLib;