You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

159 lines
6.2 KiB

import { expect } from 'chai'
import db from '../../src/db/index.js'
import { withTransaction, bulkCreate, bulkUpdate, bulkDelete } from '../../src/db/transaction.js'
import { UserModel } from '../../src/db/models/UserModel.js'
describe('Transaction Handling', () => {
before(async () => {
// 确保users表存在
const exists = await db.schema.hasTable('users')
if (!exists) {
await db.schema.createTable('users', (table) => {
table.increments('id').primary()
table.string('username').unique()
table.string('email').unique()
table.string('password')
table.timestamp('created_at').defaultTo(db.fn.now())
table.timestamp('updated_at').defaultTo(db.fn.now())
})
}
})
afterEach(async () => {
// 清理测试数据
await db('users').del()
})
describe('Basic Transactions', () => {
it('应该在事务中成功执行操作', async () => {
const result = await withTransaction(async (trx) => {
const user = await UserModel.createInTransaction(trx, {
username: 'trx_user',
email: 'trx@example.com',
password: 'password123'
})
const updated = await UserModel.updateInTransaction(trx, user.id, {
name: 'Transaction User'
})
return updated
})
expect(result).to.have.property('id')
expect(result.username).to.equal('trx_user')
expect(result.name).to.equal('Transaction User')
// 验证数据已提交到数据库
const user = await UserModel.findById(result.id)
expect(user).to.deep.equal(result)
})
it('应该在事务失败时回滚操作', async () => {
try {
await withTransaction(async (trx) => {
await UserModel.createInTransaction(trx, {
username: 'rollback_user',
email: 'rollback@example.com',
password: 'password123'
})
// 故意抛出错误触发回滚
throw new Error('测试回滚')
})
expect.fail('应该抛出错误')
} catch (error) {
expect(error.message).to.equal('测试回滚')
}
// 验证数据未保存到数据库
const user = await UserModel.findByUsername('rollback_user')
expect(user).to.be.null
})
})
describe('Bulk Operations', () => {
it('应该正确批量创建记录', async () => {
const userData = [
{ username: 'bulk1', email: 'bulk1@example.com', password: 'password123' },
{ username: 'bulk2', email: 'bulk2@example.com', password: 'password123' },
{ username: 'bulk3', email: 'bulk3@example.com', password: 'password123' }
]
const results = await bulkCreate('users', userData)
expect(results).to.have.length(3)
expect(results[0].username).to.equal('bulk1')
expect(results[1].username).to.equal('bulk2')
expect(results[2].username).to.equal('bulk3')
// 验证数据已保存
const count = await UserModel.count()
expect(count).to.equal(3)
})
it('应该正确批量更新记录', async () => {
// 先创建测试数据
const userData = [
{ username: 'update1', email: 'update1@example.com', password: 'password123' },
{ username: 'update2', email: 'update2@example.com', password: 'password123' }
]
const created = await bulkCreate('users', userData)
// 批量更新
const updates = [
{ where: { id: created[0].id }, data: { name: 'Updated User 1' } },
{ where: { id: created[1].id }, data: { name: 'Updated User 2' } }
]
const results = await bulkUpdate('users', updates)
expect(results).to.have.length(2)
expect(results[0].name).to.equal('Updated User 1')
expect(results[1].name).to.equal('Updated User 2')
})
it('应该正确批量删除记录', async () => {
// 先创建测试数据
const userData = [
{ username: 'delete1', email: 'delete1@example.com', password: 'password123' },
{ username: 'delete2', email: 'delete2@example.com', password: 'password123' },
{ username: 'keep', email: 'keep@example.com', password: 'password123' }
]
const created = await bulkCreate('users', userData)
// 批量删除前两个用户
const conditions = [
{ id: created[0].id },
{ id: created[1].id }
]
const deletedCount = await bulkDelete('users', conditions)
expect(deletedCount).to.equal(2)
// 验证只有第三个用户保留
const remaining = await UserModel.findAll()
expect(remaining).to.have.length(1)
expect(remaining[0].username).to.equal('keep')
})
})
describe('Atomic Operations', () => {
it('应该执行原子操作', async () => {
// 这个测试比较复杂,因为需要模拟并发场景
// 简单测试原子操作是否能正常执行
const result = await withTransaction(async (trx) => {
return await UserModel.createInTransaction(trx, {
username: 'atomic_user',
email: 'atomic@example.com',
password: 'password123'
})
})
expect(result).to.have.property('id')
expect(result.username).to.equal('atomic_user')
})
})
})