Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 开玩笑模拟Knex事务_Node.js_Unit Testing_Aws Lambda_Jestjs_Knex.js - Fatal编程技术网

Node.js 开玩笑模拟Knex事务

Node.js 开玩笑模拟Knex事务,node.js,unit-testing,aws-lambda,jestjs,knex.js,Node.js,Unit Testing,Aws Lambda,Jestjs,Knex.js,我有以下lambda处理程序进行单元测试。它使用一个库@org/aws connection,它有一个函数mysql.getIamConnection,该函数只返回一个knex连接 编辑:我在帖子底部添加了mysql.getIamConnection函数 编辑:如果可能的话,我只想开玩笑地做测试。除非它变得复杂 index.js const {mysql} = require('@org/aws-connection'); exports.handler = async (event) =&g

我有以下lambda处理程序进行单元测试。它使用一个库
@org/aws connection
,它有一个函数
mysql.getIamConnection
,该函数只返回一个knex连接

编辑:我在帖子底部添加了
mysql.getIamConnection
函数

编辑:如果可能的话,我只想开玩笑地做测试。除非它变得复杂

index.js

const {mysql} = require('@org/aws-connection');

exports.handler = async (event) => {
  const connection = await mysql.getIamConnection()

  let response = {
    statusCode: 200,
    body: {
      message: 'Successful'
    }
  }

  try {
    for(const currentMessage of event.Records){
      let records = JSON.parse(currentMessage.body);
      
      await connection.transaction(async (trx) => {
        await trx
            .table('my_table')
            .insert(records)
            .then(() =>
                console.log(`Records inserted into table ${table}`))
            .catch((err) => {
                console.log(err)
                throw err
            })
      })
    }
  } catch (e) {
    console.error('There was an error while processing', { errorMessage: e})

    response = {
      statusCode: 400,
      body: e
    }
  } finally {
    connection.destroy()
  }
  return response
}
我已经编写了一些单元测试,并且能够模拟
connection.transaction
函数,但是trx.select.insert.then.catch函数有问题。H

这是我的测试文件 index.test.js

import { handler } from '../src';
const mocks = require('./mocks');

jest.mock('@org/aws-connection', () => ({
    mysql: {
        getIamConnection: jest.fn(() => ({
            transaction: jest.fn(() => ({
                table: jest.fn().mockReturnThis(),
                insert: jest.fn().mockReturnThis()
            })),
            table: jest.fn().mockReturnThis(),
            insert: jest.fn().mockReturnThis(),
            destroy: jest.fn().mockReturnThis()
        }))
    }
}))

describe('handler', () => {
    test('test handler', async () =>{
      const response = await handler(mocks.eventSqs)
      expect(response.statusCode).toEqual(200)
    });
});
该测试部分工作,但根本不包括
trx
部分。这些线没有被覆盖

await trx
        .table('my_table')
        .insert(records)
        .then(() =>
            console.log(`Records inserted into table ${table}`))
        .catch((err) => {
            console.log(err)
            throw err
        })
如何设置我的mock
@org/aws连接
,使其同时涵盖trx功能

编辑: mysql.getIamConnection

async function getIamConnection (secretId, dbname) {
    const secret = await getSecret(secretId)

    const token = await getToken(secret)

    let knex
    console.log(`Initialzing a connection to ${secret.proxyendpoint}:${secret.port}/${dbname} as ${secret.username}`)
    knex = require('knex')(
        {
            client: 'mysql2',
            connection: {
                host: secret.proxyendpoint,
                user: secret.username,
                database: dbname,
                port: secret.port,
                ssl: 'Amazon RDS',
                authPlugins: {
                    mysql_clear_password: () => () => Buffer.from(token + '\0')
                },
                connectionLimit: 1
            }
        }
    )

    return knex
}
解决方案

@卡西马卡尼的回答对我很有用。我写的有点不同,但回调是关键。对任何感兴趣的人来说,这是我的最终解决方案

const mockTrx = {
    table: jest.fn().mockReturnThis(),
    insert: jest.fn().mockResolvedValue()
}

jest.mock('@org/aws-connection', () => ({
    mysql: {
        getIamConnection: jest.fn(() => ({
            transaction: jest.fn((callback) => callback(mockTrx)),
            destroy: jest.fn().mockReturnThis()
        }))
    }
}))

我没有模仿knex实现,而是编写了一个简单的API来模拟真实的db

使用更改您的模拟实现

从“./src”导入{handler};
从“knex模拟客户端”导入{getTracker};
常量模拟=需要(“./模拟”);
jest.mock(“@org/aws连接”,()=>{
const knex=要求(“knex”);
const{MockClient}=require(“knex mock client”);
返回{
mysql:{
getIamConnection:()=>knex({client:MockClient}),
},
};
});
描述(“处理程序”,()=>{
测试(“测试处理程序”,异步()=>{
const tracker=getTracker();
tracker.on.insert(“my_table”).responseOnce([23]);//在插入my_table时,安装程序是一个模拟响应
const response=await处理程序(mocks.eventSqs);
expect(response.statusCode).toEqual(200);
});
});

好的,让我们看看。将模拟更新为这样可能会达到以下目的:


const {mysql} = require('@org/aws-connection');
jest.mock('@org/aws-connectionm, () => ({
    mySql: {
        getIamConnection: jest.fn()
    }
}));


const mockTrx = {
  table: jest.fn().mockReturnThis(),
  insert: jest.fn().mockResolveValue() // resolve any data here
};
mysql.getIamConnection.mockReturnValue({
    transaction: jest.fn((callback) => callback(mockTrx)),
});

编辑:解释


您需要以一种模拟事务的方式,让它用一个伪trx调用您的回调。现在,为了使虚拟trx正确,您需要确保虚拟trx对象中的所有函数返回对它的引用或承诺,以便您可以适当地链接它。

如果
连接.事务
被成功模拟,我看不出它如何返回真实的事务对象(
trx
)在回调中?你是对的,它没有真正成功,因为它在回调中没有trx。我想这就是这个问题的重点。但是,它模拟了连接。事务。我希望用JestIt来实现这一点。模拟knex api是可能的,但不推荐,因为knex可能会更改它的api,这将破坏您的测试。尽管我最终编写的解决方案略有不同,但这个回调对我来说很有效。太棒了,很高兴它成功了。