多个字段上的 Mongoose Schema.index 不适用于测试
Mongoose Schema.index on multiple fields does not work with tests
我创建了一个 uploadSchema
(mongoose.Schema
) 字段(在其余字段中):key 和 bucket。他们每个人都不是唯一的,但我希望他们一起创建一个唯一的 ID。
在我的代码中,我使用了这一行(在声明 uploadSchema
之后和 uploadModel
之前):
uploadSchema.index({ key: 1, bucket: 1 }, { unique: true, background: true });
但是,在我的测试中(mocha
和 chai
),索引并未强制执行,因此我可以创建两个具有相同键和存储桶的实例(在我的例子中)。
例如,在我的代码中:
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;
不抛出正确的错误error:
AssertionError: expected promise to be rejected but it was fulfilled with { Object ($__, isNew, ...) }
我是不是用错了?还是索引和测试有问题?
很可能您在连接中将 autoIndex
设置为 false(建议这样做)。
要么将其添加到您的架构中:
let uploadSchema = mongoose.Schema({ ... }, {autoIndex: true});
但我建议您自己在数据库上构建索引,我认为这是最安全的方法。
所以我想通了!
显然,我在 afterEach 测试中使用了 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 是空的。
现在可以了:)
我创建了一个 uploadSchema
(mongoose.Schema
) 字段(在其余字段中):key 和 bucket。他们每个人都不是唯一的,但我希望他们一起创建一个唯一的 ID。
在我的代码中,我使用了这一行(在声明 uploadSchema
之后和 uploadModel
之前):
uploadSchema.index({ key: 1, bucket: 1 }, { unique: true, background: true });
但是,在我的测试中(mocha
和 chai
),索引并未强制执行,因此我可以创建两个具有相同键和存储桶的实例(在我的例子中)。
例如,在我的代码中:
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;
不抛出正确的错误error:
AssertionError: expected promise to be rejected but it was fulfilled with { Object ($__, isNew, ...) }
我是不是用错了?还是索引和测试有问题?
很可能您在连接中将 autoIndex
设置为 false(建议这样做)。
要么将其添加到您的架构中:
let uploadSchema = mongoose.Schema({ ... }, {autoIndex: true});
但我建议您自己在数据库上构建索引,我认为这是最安全的方法。
所以我想通了!
显然,我在 afterEach 测试中使用了 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 是空的。 现在可以了:)