You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS E2E测试中Mongoose find无法返回MongoDB文档

问题描述

我采用E2E测试方案验证NestJS应用向MongoDB写入文档的数量:通过Jest对Docker中运行的应用发起HTTP请求,之后查询MongoDB文档并验证数量。但调用mongoose的find({})始终返回空数组,而MongoDB Compass显示集合中确实存在文档。

应用Schema定义

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type MyDocument = MyData & Document;

@Schema({timestamps: true, autoIndex:false, collection: 'my_documents'})
export class MyData {
    @Prop({ required: true })
    message: string;
}

export const MySchema = SchemaFactory.createForClass(MyData);

测试代码

import { MyData, MySchema } from 'apps/api/src/app/schema';
import axios from 'axios';
import { connect, model } from 'mongoose';
import { resetDb, sleep } from '../support/helpers';

describe('Post twice, then get', () => {
  beforeEach(async () => {
    await resetDb();
    // let things settle
    await sleep(10000);
  });

  it('should return two messages', async () => {
    const deleteResult = await axios.delete('/');
    expect(deleteResult.status).toBe(200);
    const post1 = await axios.post('/', { message: 'Hello' });
    expect(post1.status).toBe(201);
    const post2 = await axios.post('/', { message: 'Hello2' });
    expect(post2.status).toBe(201);

    const res = await axios.get('/');

    expect(res.status).toBe(200);
    await connect(process.env.MONGODB_URI);
    const myModel = model<MyData>('MyData', MySchema);
    const documents = await myModel.find({});
    console.log(documents);
    expect(documents.length).toBe(2);
  });
});

复现方式

基于NX monorepo创建了最小可复现项目,在仓库根目录执行命令 npx nx e2e api-e2e,该命令会自动构建并Docker化应用,通过Docker Compose启动MongoDB和应用容器。


问题排查与解决

1. 模型与集合名称不匹配

你的Schema明确指定了集合名为my_documents,但创建模型时仅传入了MyData作为模型名。Mongoose默认会将模型名转为复数小写形式作为集合名(此处会生成mydatas),导致测试代码查询的是错误集合,自然返回空数组。

解决代码:创建模型时显式指定集合名称:

const myModel = model<MyData>('MyData', MySchema, 'my_documents');

2. 数据库连接管理问题

测试用例中每次执行都调用connect建立新连接,可能存在连接未就绪、多连接冲突的情况。建议统一管理连接生命周期:

import mongoose from 'mongoose';

describe('Post twice, then get', () => {
  beforeAll(async () => {
    await mongoose.connect(process.env.MONGODB_URI);
  });

  afterAll(async () => {
    await mongoose.disconnect();
  });

  // 其余测试代码不变
});

3. 写入操作未完成持久化

虽然HTTP请求返回201状态码,但应用端的数据库写入可能还未完成持久化。可在POST请求后增加短暂等待,或确保应用端的写入逻辑是同步完成的:

const post2 = await axios.post('/', { message: 'Hello2' });
expect(post2.status).toBe(201);
await sleep(500); // 增加短暂等待

4. 环境变量数据库地址不一致

确认测试代码中process.env.MONGODB_URI与应用连接的MongoDB地址完全一致。比如应用连接的是Docker容器内的mongodb://mongo:27017/test,而测试代码可能连接的是本地mongodb://localhost:27017/test,导致查询的数据库实例不匹配。

内容的提问来源于stack exchange,提问作者dfsg76

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:05:33