node.js - Jest 模拟 Knex 交易

标签 node.js unit-testing aws-lambda jestjs knex.js

我有以下 lambda 处理程序进行单元测试。它使用一个库 @org/aws-connection其中有一个函数 mysql.getIamConnection它只是返回一个 knex 连接。
编辑:我添加了 mysql.getIamConnection功能到帖子底部
编辑:如果可能,我只想用 Jest 进行测试。除非它变得复杂
索引.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
        })
如何设置我的模拟 @org/aws-connection以便它也涵盖 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
}
解决方案
@qaismakani 的回答对我有用。我写的略有不同,但回调是关键。对于任何感兴趣的人来说,这是我的最终解决方案
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()
        }))
    }
}))

最佳答案

好吧,让我们看看。更新你的模拟看起来像这样可能会成功:


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 对象中的所有函数都返回对它的引用或 promise ,以便您可以适本地链接它。

关于node.js - Jest 模拟 Knex 交易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67631617/

相关文章:

node.js - 在 Nodejs 中使用 postgresql 时,我应该如何从网络服务器查询数据库?

node.js - 如何在数据库调用之外的 mongoIds 数组中找到 mongoId

java - Mockito:如何验证来自另一个单例类的单例类的方法调用

unit-testing - 使用 Spring MockMvc* 类测试 Spring MVC Controller 方法

aws-lambda - Saxon XSLT 转换作为 Amazon AWS Lambda 函数交付

node.js - Alexa Skills Kit Lambda 区域问题

API Gateway POST 方法在测试期间有效,但不适用于 postman

node.js - 使用 Node Traceur 编译 ecma 脚本 6

node.js - NodeJS、Express - 将 EJS View 渲染到下载文件

java - 在调用层次结构中插入模拟对象