【问题标题】:Mongoose Schema.index on multiple fields does not work with tests多个字段上的 Mongoose Schema.index 不适用于测试
【发布时间】:2019-10-24 12:43:48
【问题描述】:

我创建了一个uploadSchema (mongoose.Schema),其中包含以下字段:密钥和存储桶。他们每个人都不是唯一的,但我希望他们一起创建一个唯一的 ID。 在我的代码中,我使用了该行(在声明 uploadSchema 之后和 uploadModel 之前):

uploadSchema.index({ key: 1, bucket: 1 }, { unique: true, background: true });

但是,在我的测试中(mochachai),没有强制执行索引,因此我可以创建两个具有相同键和存储桶的实例(在我的情况下)。 例如,在我的代码中:

await uploadModel.create({ key: testUpload.key, bucket: testUpload.bucket, 
name: 'name1',  ownerID: USER.id, parent: null }).should.eventually.exist;

然后:

await uploadModel.create({key: testUpload.key, bucket: testUpload.bucket,
 name: 'name1', ownerID: USER.id, parent: null }).should.eventually.be.rejected;

不抛出正确的错误错误:

AssertionError: expected promise to be rejected but it was fulfilled with { Object ($__, isNew, ...) }

我没有正确使用它吗?还是索引和测试有问题?

【问题讨论】:

    标签: javascript typescript mongoose mocha.js chai-as-promised


    【解决方案1】:

    您很可能在连接中将 autoIndex 设置为 false(建议这样做)。

    要么将其添加到您的架构中:

    let uploadSchema = mongoose.Schema({ ... }, {autoIndex: true});

    但我建议自己在数据库上建立索引,我认为这是最安全的方法。

    【讨论】:

    • autoIndex 没有修复它,我不想手动做,因为我们有 jenkins 的自动测试,所以它不会通过
    • 您能分享一下该数据库中已经建立了哪些索引吗?
    【解决方案2】:

    所以我想通了! 显然,我在之后的每个测试中都使用了mongoose.connection.dropDatabase();。这意味着每次都会重置索引。 所以我所做的是每次在我的测试中重新创建索引:

      before(async () => {
        // Remove files from DB
        const collections = ['files', 'uploads'];
        for (const i in collections) {
          mongoose.connection.db.createCollection(collections[i], (err) => {});
        }
        await mongoose.connection.collections['files'].createIndex({ name: 1, parent: 1, ownerID: 1 }, { unique: true });
        await mongoose.connection.collections['uploads'].createIndex({ key: 1, bucket: 1 }, { unique: true });
      });
    

    并且在 beforeEach 中:

      beforeEach(async () => {
        const removeCollectionPromises = [];
        for (const i in mongoose.connection.collections) {
          removeCollectionPromises.push(mongoose.connection.collections[i].deleteMany({}));
        }
        await Promise.all(removeCollectionPromises);
      });
    

    afterEach 为空。 现在可以了:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-06
      • 2023-03-16
      • 2019-03-30
      • 2017-05-20
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多