【发布时间】:2019-10-07 06:22:50
【问题描述】:
我首先要说明我对表达和后端编程还很陌生。我不知道如何格式化我的问题,如果有重复,请转发给他们。
我创建了一个 express 应用程序,我在其中使用 mongoDB 和各种工具为即将发布的博客创建一个 API,该博客将成为一个 react 应用程序。到目前为止,我一直做得很好,并且已经开始使用 get、post 和 delete 方法。当我开始创建我的 put 方法时,我遇到了问题。我已经为我的 put 请求创建了一个 mongoose Schema,一个路由器,并使用“findByIdAndUpdate”来更新我的数据库。对于测试,我使用 jest 和 supertest。
我遇到的问题是,当我尝试根据其 ID 更新数据库中的对象时,即使我的数据库中的对象成功更新,我也会收到 500“内部服务器错误”。鉴于即使显然存在服务器错误,请求也会通过,我没有答案。
我尝试过的:
我在所有相关代码周围使用了 try/catch 块,但我的错误日志并没有真正给我任何答案。
我已经使用 supertest 和 jest 制作了一个测试文件来测试这个以及我之前的所有操作,除了这个之外,这些操作都运行良好。
我已使用 VS Code REST 客户端插件更新我的数据库。
我尝试让我的超级测试 expect(500),这使测试继续并通过,从而确认尽管服务器错误,对象仍会更新。
我的博客模型,使用 Mongoose Schema
const mongoose = require('mongoose')
const blogSchema = mongoose.Schema({
title: {
type: String,
required: true
},
author: String,
url: {
type: String,
required: true
},
likes: Number
})
blogSchema.set('toJSON', {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString()
delete returnedObject._id
delete returnedObject.__v
}
})
module.exports = mongoose.model('Blog', blogSchema)
我的路由器
const blogsRouter = require('express').Router()
const Blog = require('../models/blog')
blogsRouter.put('/:id', async (req, res, next) => {
const body = req.body
const blog = {
title: body.title
}
try {
const updatedBlog = await Blog.findByIdAndUpdate(req.params.id, blog, {
new: true
})
console.log("Updated blog: ", updatedBlog)
res.json(updatedBlog.toJSON())
} catch (err) {
next(err)
}
})
module.exports = blogsRouter
我的 test_helper.js 文件
const Blog = require('../models/blog')
const initialBlogs = [
{
title: 'testTitle',
author: 'testAuthor',
url: 'testUrl',
likes: 3
},
{
title: 'anotherTest',
author: 'anotherAuthor',
url: 'anotherUrl',
likes: 25
}
]
const nonExistingId = async () => {
const blog = new Blog({ title: 'willremovethissoon' })
await blog.save()
await blog.remove()
return blog._id.toString()
}
const blogsInDb = async () => {
const blogs = await Blog.find({})
return blogs.map(blog => blog.toJSON())
}
module.exports = {
initialBlogs,
nonExistingId,
blogsInDb
}
我的 blogs_api.test.js 文件
const mongoose = require('mongoose')
const supertest = require('supertest')
const helper = require('./test_helper')
const app = require('../app')
const api = supertest(app)
const Blog = require('../models/blog')
describe('when there is initially some blogs saved', () => {
beforeEach(async () => {
await Blog.remove({})
for (let blog of helper.initialBlogs) {
let blogObject = new Blog(blog)
await blogObject.save()
}
})
describe('updating of blogs', () => {
test('a blog can be updated', async () => {
const blog = {
title:
'updatedTitle - this gets through even thought Im getting 500
"internal server error"'
}
const blogsAtStart = await helper.blogsInDb()
const blogToUpdate = blogsAtStart[0]
console.log('Blog to update: ', blogToUpdate)
await api
.put(`/api/blogs/${blogToUpdate.id}`)
.send(blog)
.expect(200)
const blogsAtEnd = await helper.blogsInDb()
const blogAfterUpdate = blogsAtEnd[0]
expect(blogAfterUpdate.title).toBe(blog.title)
})
})
})
尝试更新对象时的日志
jonas$ jest -t updated
FAIL tests/blog_api.test.js
Console
console.log tests/blog_api.test.js:129
Blog to update: { title: 'testTitle',
author: 'testAuthor',
url: 'testUrl',
likes: 3,
id: '5ce30cbfd3ed531b538579ac' }
console.log controllers/blogs.js:62
Updated blog: { _id: 5ce30cbfd3ed531b538579ac,
title:
'updatedTitle - this gets through even thought Im getting 500 "internal server error"',
author: 'testAuthor',
url: 'testUrl',
likes: 3,
__v: 0 }
console.log utils/logger.js:8
updatedBlog.toJSON is not a function
when there is initially some blogs saved › updating of blogs › a
blog can be updated
expected 200 "OK", got 500 "Internal Server Error"
at Test.Object.<anonymous>.Test._assertStatus (node_modules/supertest/lib/test.js:268:12)
at Test.Object.<anonymous>.Test._assertFunction (node_modules/supertest/lib/test.js:283:11)
at Test.Object.<anonymous>.Test.assert (node_modules/supertest/lib/test.js:173:18)
at Server.localAssert (node_modules/supertest/lib/test.js:131:12)
如前所述,对象正在正确更新到我的数据库中,但在解决此错误之前我无法继续。让我自己调试变得如此困难的原因是对象在开发和测试环境中都正确更新到我的数据库中。
我尝试发布尽可能少的代码,如果需要更多代码,或者问题不清楚,请告诉我。我包含测试文件只是为了更好地解释我的控制台日志,请说明它们是否不必要。
【问题讨论】:
-
即使删除 toJSON() 似乎有效,但故障并不存在。我将 mongoose 版本从 5.5.3 更新到 5.5.10,并且能够像上面一样执行代码,将 id 从对象重新格式化为字符串并从对象中删除 __v 键。我不确定将来在更新对象时是否需要 toJSON(),因为我在获取对象时会使用它。但至少它按预期工作,问题出在猫鼬版本上。
标签: node.js mongodb express mongoose internal-server-error