Mongoose 聚合查询在 Jest/Mockgoose 测试中失败,在其他地方有效
Mongoose aggregation query fails in Jest/Mockgoose test, works elsewhere
我正在尝试为我的 Mongoose 模型创建一些测试,但我不知道如何让 Jest/Mockgoose 测试通过 shorthand query/aggregation 我创建的用于从一个集合中检索未在另一个集合中引用的随机文档的管道(见下文第一个代码块)。
activitySchema.query.getUnused = function() {
return Activity.aggregate()
.lookup({
from: 'userActivity',
localField: '_id',
foreignField: 'activity',
as: 'matched_docs',
})
.match({ matched_docs: { $eq: [] } })
.sample(1)
.project({ matched_docs: 0, __v: 0 })
.exec()
}
笑话测试
describe('Activity methods', () => {
test('Activity unused query executes', (done) => {
function createActivity() {
return Activity
.create({ activity: 'running' })
.then(activity => {
console.log('Activity is generated')
return Promise.resolve(true)
})
}
async function retrieveActivity() {
await createActivity()
Activity
.find()
.getUnused()
.then(unused => {
console.log(unused);
expect(unused).toHaveLength(1)
done()
})
.catch(x => {
console.log(x)
})
}
return retrieveActivity()
})
})
沙盒节点 JS 代码:
Activity.find().getUnused()
.then((x) => {
console.log(x);
})
当我在沙箱节点文件中尝试时,机智正常工作并检索典型的查询集,如:
[ { _id: 58f3dee3b0346910a69e6e5d, activity: 'running', __v: 0 } ]
当我运行测试时,我得到这个Mongo错误:
The 'cursor' option is required, except for aggregation explain
如何使用在两种情况下都适用的通用方式解决此问题?如果可能的话,我希望该方法能够 return 一个承诺。我已经尝试了链式聚合方法(见上文)和更原生的 Mongo 管道聚合数组,但都 return 错误。如果相关的话,我的 mongo 版本是 3.4.2。
终于想通了:我必须向聚合管道添加游标调用,并将其转换为流。为了维护 Promise,我使用了查询方法
return 流结束后用数据解析的 Promise,如下所示:
activitySchema.query.getUnused = function() {
return new Promise((res, rej) => {
let data = []
return Activity.aggregate()
.lookup({
from: 'userActivity',
localField: '_id',
foreignField: 'activity',
as: 'matched_docs',
})
.match({ matched_docs: { $eq: [] } })
.sample(1)
.project({ matched_docs: 0, __v: 0 })
.cursor({})
.exec()
.on('data', doc => data.push(doc))
.on('end', () => res(data))
})
}
我遇到过类似的问题,经过大量研究后我发现这是由于旧版本的猫鼬造成的,因为早期版本与 MongoDB 3.6 及更高版本中的重大更改不兼容。
我一个一个升级了 mongoose 版本,我发现它在 mongoose 版本 4.12.2
或更高版本 (mongoose@4.12.2).
上工作得很好
您可以通过运行以下命令升级您的猫鼬版本:
npm install mongoose@4.12.2
我正在尝试为我的 Mongoose 模型创建一些测试,但我不知道如何让 Jest/Mockgoose 测试通过 shorthand query/aggregation 我创建的用于从一个集合中检索未在另一个集合中引用的随机文档的管道(见下文第一个代码块)。
activitySchema.query.getUnused = function() {
return Activity.aggregate()
.lookup({
from: 'userActivity',
localField: '_id',
foreignField: 'activity',
as: 'matched_docs',
})
.match({ matched_docs: { $eq: [] } })
.sample(1)
.project({ matched_docs: 0, __v: 0 })
.exec()
}
笑话测试
describe('Activity methods', () => {
test('Activity unused query executes', (done) => {
function createActivity() {
return Activity
.create({ activity: 'running' })
.then(activity => {
console.log('Activity is generated')
return Promise.resolve(true)
})
}
async function retrieveActivity() {
await createActivity()
Activity
.find()
.getUnused()
.then(unused => {
console.log(unused);
expect(unused).toHaveLength(1)
done()
})
.catch(x => {
console.log(x)
})
}
return retrieveActivity()
})
})
沙盒节点 JS 代码:
Activity.find().getUnused()
.then((x) => {
console.log(x);
})
当我在沙箱节点文件中尝试时,机智正常工作并检索典型的查询集,如:
[ { _id: 58f3dee3b0346910a69e6e5d, activity: 'running', __v: 0 } ]
当我运行测试时,我得到这个Mongo错误:
The 'cursor' option is required, except for aggregation explain
如何使用在两种情况下都适用的通用方式解决此问题?如果可能的话,我希望该方法能够 return 一个承诺。我已经尝试了链式聚合方法(见上文)和更原生的 Mongo 管道聚合数组,但都 return 错误。如果相关的话,我的 mongo 版本是 3.4.2。
终于想通了:我必须向聚合管道添加游标调用,并将其转换为流。为了维护 Promise,我使用了查询方法 return 流结束后用数据解析的 Promise,如下所示:
activitySchema.query.getUnused = function() {
return new Promise((res, rej) => {
let data = []
return Activity.aggregate()
.lookup({
from: 'userActivity',
localField: '_id',
foreignField: 'activity',
as: 'matched_docs',
})
.match({ matched_docs: { $eq: [] } })
.sample(1)
.project({ matched_docs: 0, __v: 0 })
.cursor({})
.exec()
.on('data', doc => data.push(doc))
.on('end', () => res(data))
})
}
我遇到过类似的问题,经过大量研究后我发现这是由于旧版本的猫鼬造成的,因为早期版本与 MongoDB 3.6 及更高版本中的重大更改不兼容。
我一个一个升级了 mongoose 版本,我发现它在 mongoose 版本 4.12.2
或更高版本 (mongoose@4.12.2).
您可以通过运行以下命令升级您的猫鼬版本:
npm install mongoose@4.12.2