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
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')
|
|
})
|
|
})
|
|
})
|