如何用Mocha/Chai测试Mongoose CRUD操作?交易处理函数测试遇数据库调用未执行问题
如何使用Mocha/Chai测试Mongoose的CRUD操作?
先搞定环境与测试前置准备
首先得把依赖装齐,推荐用内存数据库测试,避免污染真实数据:
npm install mocha chai mongoose mongodb-memory-server --save-dev
然后用Mocha的钩子做测试前后的数据库管理,保证每次测试都是干净的环境:
const mongoose = require('mongoose'); const { MongoMemoryServer } = require('mongodb-memory-server'); const { expect } = require('chai'); let mongoServer; // 测试前启动内存数据库并连接 before(async () => { mongoServer = await MongoMemoryServer.create(); await mongoose.connect(mongoServer.getUri()); }); // 测试完成后断开连接并关闭内存数据库 after(async () => { await mongoose.disconnect(); await mongoServer.stop(); }); // 每个测试用例前清空目标集合 beforeEach(async () => { await mongoose.connection.collection('users').deleteMany({}); });
逐个写CRUD的测试用例
假设你有个User模型:
const userSchema = new mongoose.Schema({ name: String, email: { type: String, unique: true } }); const User = mongoose.model('User', userSchema);
测试Create(创建)
describe('User CRUD 测试', () => { it('应该能创建一个新用户', async () => { const user = new User({ name: 'Alice', email: 'alice@test.com' }); const savedUser = await user.save(); expect(savedUser._id).to.exist; expect(savedUser.name).to.equal('Alice'); expect(savedUser.email).to.equal('alice@test.com'); }); });
测试Read(读取)
it('应该能通过邮箱找到用户', async () => { await User.create({ name: 'Bob', email: 'bob@test.com' }); const foundUser = await User.findOne({ email: 'bob@test.com' }); expect(foundUser).to.not.be.null; expect(foundUser.name).to.equal('Bob'); });
测试Update(更新)
it('应该能更新用户的名字', async () => { const user = await User.create({ name: 'Charlie', email: 'charlie@test.com' }); await User.updateOne({ _id: user._id }, { name: 'Charlie Brown' }); const updatedUser = await User.findById(user._id); expect(updatedUser.name).to.equal('Charlie Brown'); });
测试Delete(删除)
it('应该能删除指定用户', async () => { const user = await User.create({ name: 'Dave', email: 'dave@test.com' }); await User.deleteOne({ _id: user._id }); const deletedUser = await User.findById(user._id); expect(deletedUser).to.be.null; });
测试交易处理函数时数据库调用未执行的排查与解决
从你描述的情况来看,函数本身和其他测试都正常,但这个交易处理逻辑里的数据库操作没跑起来,大概率是异步处理没做好,或者测试环境的细节没注意到,咱们一步步排查:
1. 先检查测试是否正确等待异步操作完成
你的交易处理函数肯定是异步的(涉及数据库和API调用),如果测试里没等它执行完就结束,Mocha会直接跳过异步逻辑。比如:
// 错误示例:没处理异步,测试直接结束 it('应该处理未完成的交易', () => { processTransactions(getPrices()); // 这个函数是异步的,但测试没等它 });
改成async/await或者返回Promise:
// 正确示例:等待异步函数执行完成 it('应该处理未完成的交易', async () => { // 先插入测试用的未完成交易 await Transaction.create([ { status: 'pending', price: 100, traderId: '123' }, { status: 'pending', price: 200, traderId: '456' } ]); // 模拟API返回的价格数组 const mockPrices = [100, 200]; // 等待交易处理函数执行完毕 await processTransactions(mockPrices); // 验证数据库变化:检查交易是否平仓、余额是否更新 const closedTransactions = await Transaction.find({ status: 'closed' }); expect(closedTransactions.length).to.equal(2); const trader = await Trader.findById('123'); expect(trader.balance).to.be.greaterThan(0); });
2. 检查API调用函数的Mock是否正确
你说这个函数依赖另一个API调用函数的返回值,如果Mock这个API函数时没正确处理异步,会导致交易逻辑提前终止。比如:
// 错误示例:Mock的API函数没返回Promise const getPrices = () => [100, 200]; // 正确示例:Mock异步API函数 const getPrices = async () => [100, 200]; // 或者用sinon工具Mock const sinon = require('sinon'); sinon.stub(apiModule, 'getPrices').resolves([100, 200]);
3. 排查数据库操作是否被吞了错误或未提交事务
如果你的处理函数用了Mongoose事务,或者有try/catch但没抛出错误,可能导致数据库操作没执行就结束:
// 错误示例:忘记提交事务,或者吞了错误 async function processTransactions(prices) { try { const session = await mongoose.startSession(); session.startTransaction(); const pendingTransactions = await Transaction.find({ status: 'pending' }).session(session); // ...处理匹配逻辑 // 忘记提交事务! // await session.commitTransaction(); } catch (err) { // 没抛出错误,测试里看不到问题 console.log(err); } }
解决办法:确保事务正确提交,并且在catch里抛出错误,或者在测试里捕获错误验证。
4. 加日志定位哪一步出问题
如果还是找不到原因,在交易处理函数的关键步骤加日志:
async function processTransactions(prices) { console.log('开始处理未完成交易'); const pendingTransactions = await Transaction.find({ status: 'pending' }); console.log(`找到 ${pendingTransactions.length} 条未完成交易`); for (const tx of pendingTransactions) { console.log(`处理交易 ${tx._id},价格:${tx.price}`); // ...匹配价格、平仓、更新余额的逻辑 } }
运行测试时看日志,就能知道是哪一步没执行,快速定位问题。
内容的提问来源于stack exchange,提问作者burningserenity
相关产品推荐
相关产品推荐

