简体   繁体   English

通过 Tedious with Jest 测试连接到 SQL 服务器的 NodeJS function,抛出错误:无法重新定义属性:连接

[英]Testing a NodeJS function that connects to SQL Server through Tedious with Jest, throws error: Cannot redefine property: Connection

Trying to test a Tedious connector function with Jest.尝试用 Jest 测试 Tedious 连接器 function。

In code-file db_server.js I have this function below, it works as expected.在代码文件db_server.js中,我在下面有这个 function,它按预期工作。

const AWS = require('aws-sdk')
const tedious = require('tedious')
const Request = require('tedious').Request;
const Connection = require('tedious').Connection;

exports.execSQLCmd = async function (conn_store, cmd) {
let config = await exports.getParameter(conn_store)
let conn_cfg = JSON.parse(config)

//connect
const connection = new Connection(conn_cfg);
connection.on('connect', function (err) {
    if (err) {
        console.log('CONNECTION ERROR: ' + err);
    }

    console.log('CONNECTED TO: ' + conn_cfg.server);
    executeStatement();
});
connection.connect();

//execute the sql command   
let result = '';
function executeStatement() {
    let request = new Request(cmd, function (err) {
        if (err) {
            console.log('REQUEST ERROR: ' + err);
        }
    });
    //add three event hooks to the request
    request.on('row', function (columns) {
        columns.forEach(function (column) {
            result += (column.value === null ? '' : column.value) + ',';
        });
        result = result.replace(/,$/, '\r\n')
    });
    request.on('done', function (rowCount, more) {
        console.log('SQL COMMAND COMPLETED: ' + rowCount + ' rows returned');
    });
    request.on('requestCompleted', function (rowCount, more) {
        connection.close();
        console.log('CONNECTION TO SERVER CLOSED');
    });

    connection.execSql(request);
}

return result;

}

exports.Request = Request
exports.Connection = Connection
exports.tedious = tedious

In the test file index.spec.js , I have the following test:在测试文件index.spec.js中,我有以下测试:

describe('Test execSQLCmd', () => {
const server = require("../src/db_server.js")

afterEach(() => {
  jest.restoreAllMocks();
});
    


test('should query sql', async () => {
server.getParameter = jest.fn().mockReturnValue('{"xxx":123,"yyy":"hello"}') 
server.execSQLCmd = jest.fn().mockReturnThis()
const TedConnect = jest.spyOn(server.tedious, 'Connection').mockReturnValue(jest.fn(() => ({
             connect: () => {},
             on: (connect, cb) => cb(),
             close: () => {},
             execSql: () => {}
  })));

  const TedRequest = jest.spyOn(server.tedious, 'Request').mockReturnValue(jest.fn(() => ({
              constructor: (sqlString, cb) => cb('err', null, null),
              on: [
                    (row, cb)=> cb('columns'),
                    (done, cb)=> cb('rowCount', 'more'),
                    (requestCompleted, cb) => cb('rowCount', 'more')
                  ]
  })));
  
  let exec = server.execSQLCmd("/pstore/name", "select 1")
  expect(TedConnect).toBeCalledTimes(1)
  expect(TedRequest).toBeCalledTimes(1)
  

})


})

When I try to run the test, I get this error:当我尝试运行测试时,出现此错误:

Test execSQLCmd › should query sql测试 execSQLCmd › 应该查询 sql

TypeError: Cannot redefine property: Connection
    at Function.defineProperty (<anonymous>)

  298 |     server.getParameter = jest.fn().mockReturnValue('{"xxx":123,"yyy":"hello"}')
  299 |     server.execSQLCmd = jest.fn().mockReturnThis()
> 300 |     const TedConnect = jest.spyOn(server.tedious, 'Connection').mockReturnValue(jest.fn(() => ({
      |                             ^
  301 |                  connect: () => {},
  302 |                  on: (connect, cb) => cb(),
  303 |                  close: () => {},

  at ModuleMockerClass.spyOn (node_modules/jest-mock/build/index.js:826:16)
  at Object.<anonymous> (__tests__/index.spec.js:300:29)

  Test Suites: 1 failed, 1 total

"tedious": "^14.1.0"
"jest": "^26.6.3",

I'm not seeing why this test fails.我不明白为什么这个测试失败了。

Any help appreciated, thanks!任何帮助表示赞赏,谢谢!

EDIT编辑

Above error not happening after the fiollowing Test changes:以下测试更改后不会发生上述错误:

test('should query sql', async () => {
    server.getParameter = jest.fn().mockReturnValue('{"xxx":123,"yyy":"hello"}') 
    server.execSQLCmd = jest.fn().mockReturnThis()
    server.Connection = jest.fn().mockReturnValue(jest.fn(() => ({
  connect: () => {},
  on: (connect, cb) => cb(),
  close: () => {},
  execSql: () => {}
}))) 

server.Request = jest.fn().mockReturnValue(jest.fn(() => ({
  constructor: (sqlString, cb) => cb('err', null, null),
  //addParameter: (name, type, value) => {},
  on: [
        (row, cb)=> cb('columns'),
        (done, cb)=> cb('rowCount', 'more'),
        (requestCompleted, cb) => cb('rowCount', 'more')
      ]
  }))) 

  let exec = server.execSQLCmd("/pstore/name", "select 1")
  expect(server.Connection).toBeCalledTimes(1)
  expect(server.Request).toBeCalledTimes(1)

 })

However, now server.execSQLCmd does't run, I cannot step into it with debug, exists right away and returns a large mock object.但是,现在 server.execSQLCmd 没有运行,我无法通过调试进入它,立即存在并返回一个大的模拟 object。

Anyone see what I'm doing wrong here?有人看到我在这里做错了吗?

Thanks!谢谢!

exports.execSQLCmd = async function (conn_store, cmd) {
    
    let config = await exports.getParameter(conn_store)
    let conn_cfg = JSON.parse(config)

    //connect
    exports.connect_exec(conn_cfg, cmd);    

    return result;
}

function connect_exec(conn_cfg, cmd) {
    const connection = exports.get_connection(conn_cfg);
    exports.on_connect(connection, cmd);
    connection.connect();
    return connection;
}

function on_connect(connection, cmd) {
    connection.on('connect', function (err) {
        if (err) {
            console.log('CONNECTION ERROR: ' + err);
        }
        console.log('CONNECTED');
        exports.execute_statement(connection, cmd);
    });
}

function get_connection(conn_cfg) {
    return new Connection(conn_cfg);
}

function execute_statement(connection, cmd) {
    let request = exports.get_request(connection, cmd);

    connection.execSql(request);
}

function get_request(connection, cmd) {
    let request = new Request(cmd, function (err) {
        if (err) {
            console.log('REQUEST ERROR: ' + err);
        }
    });
    //add three event hooks to the request
    request.on('row', function (columns) {
        columns.forEach(function (column) {
            result += (column.value === null ? '' : column.value) + ',';
        });
        result = result.replace(/,$/, '\r\n');
    });
    request.on('done', function (rowCount, more) {
        console.log('SQL COMMAND COMPLETED: ' + rowCount + ' rows returned');
    });
    request.on('requestCompleted', function (rowCount, more) {
        connection.close();
        console.log('CONNECTION TO SERVER CLOSED');
    });
    return request;
}

exports.AWS = AWS;

exports.connect_exec = connect_exec
exports.execute_statement = execute_statement
exports.get_request = get_request
exports.get_connection = get_connection
exports.on_connect = on_connect

Here's my test:这是我的测试:

describe('Test execSQLCmd', async () => {
    const server = require("../src/opportunity/db_server.js")
     
      afterEach(() => {
      jest.restoreAllMocks();
    });

   test('should query sql', async () => {
    server.getParameter = jest.fn().mockReturnValue('{"xxx":123,"yyy":"hello"}') 
    
    server.get_connection = jest.fn().mockReturnValue({
      connect: () => {},
      on: (connect, cb) => cb(),
      close: () => {} ,
      execSql: () => {}
    }) 

    server.get_request = jest.fn().mockReturnValue({
      constructor: (sqlString, cb) => cb('err', null, null),
      on: [
            (row, cb)=> cb('columns'),
            (done, cb)=> cb('rowCount', 'more'),
            (requestCompleted, cb) => cb('rowCount', 'more')
          ]
      })
    
      await server.execSQLCmd("/pstore/name", "select 1")      
      expect(server.get_connection).toHaveBeenCalled()
      expect(server.get_request).toHaveBeenCalled()
   })
}) 

Took me a day to write all the code for main functionality, ore than there is here.我花了一天时间编写主要功能的所有代码,比这里的要多。

Took me 2.5 days to figure out just this test.我花了 2.5 天的时间才搞清楚这个测试。 Silly!愚蠢的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jest - 测试 function 抛出错误不起作用 - Jest - Testing function that throws an error not working 开玩笑测试 Vue 组件抛出错误“无法读取未定义的‘键’……” - Jest Testing Vue Component throws Error “cannot read undefined 'key'…” jest js:wicg-inert包含不能重新定义属性惰性 - jest js: wicg-inert included cannot redefine property inert 获取类型错误:无法重新定义属性:使用 Jest spyOn 时使用导航 - Get TypeError: Cannot redefine property: useNavigate when using Jest spyOn 用 Jest 模拟 axios 会引发错误“无法读取未定义的属性‘拦截器’” - Mocking axios with Jest throws error “Cannot read property 'interceptors' of undefined” jest spyOn 无法处理索引文件,无法重新定义属性 - jest spyOn not working on index file, cannot redefine property 无法读取属性 'tagName' 的 null 错误反应测试库与开玩笑 - Cannot read property 'tagName' of null error in react testing library with jest 类型错误:无法使用 JEST 单元测试读取 NodeJS 中未定义的属性“应用” - TypeError: Cannot read property 'apply' of undefined in NodeJS using JEST unit testing React Jest DynamoDb 测试抛出错误 ENOENT - React Jest DynamoDb Testing throws error ENOENT 测试 Function 在 Jest 中抛出错误 - Testing Function to Throw an Error in Jest
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM