[英]Jest mock Knex transaction
我有以下 lambda 處理程序進行單元測試。 它使用一個庫@org/aws-connection
,它有一個function mysql.getIamConnection
,它只返回一個knex連接。
編輯:我已將mysql.getIamConnection
function 添加到帖子底部
編輯:如果可能的話,我想只用 Jest 進行測試。 那是除非它變得復雜
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
function 但我遇到了 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()
}))
}
}))
我編寫knex-mock-client
而不是 mocking knex 實現,它允許您使用簡單的 API 模擬真實數據庫。
更改您的模擬實現
import { handler } from "../src";
import { getTracker } from "knex-mock-client";
const mocks = require("./mocks");
jest.mock("@org/aws-connection", () => {
const knex = require("knex");
const { MockClient } = require("knex-mock-client");
return {
mysql: {
getIamConnection: () => knex({ client: MockClient }),
},
};
});
describe("handler", () => {
test("test handler", async () => {
const tracker = getTracker();
tracker.on.insert("my_table").responseOnce([23]); // setup's a mock response when inserting into my_table
const response = await handler(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,您需要確保 dummy trx object 中的所有函數都返回對它的引用或 promise,以便您可以適當地鏈接它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.