Как использовать Sinon для остановки взаимодействия с базой данных с помощью библиотеки mssql?

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

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, чтобы заглушить его.

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


person jcollum    schedule 28.07.2016    source источник


Ответы (1)


Ну, мне удалось решить это, но по какой-то причине это кажется немного хакерским. Возможно, потому что я так и не понял, как заглушить вызов 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;
person jcollum    schedule 28.07.2016