我正在运行登录控制器的测试,它一直给出错误的状态代码(401)而不是200,因为我编程它。 我希望它能够使用用户注册时存储的数据,并在给定输入正确时返回它。 它在邮递员中完美运行,但在我编写测试时,它会抛出401错误。 它就像它没有找到用户
这是登录的测试块:
it('it should signin a new user', (done) => {
request(app)
.post('/api/users/signin')
.send({
username: "Charles",
password: "challenger",
})
.expect(200)
.end((err, res) => {
if (err) {
return done(err);
}
done()
});
});
这是我登录的控制器:
signin(req, res) {
const username = req.body.username.toLowerCase().trim();
// const email = req.body.email.trim();
if(!username) {
return res.status(401)
.send(
{status: false,
message: "Username cannot be empty"
});
}
else if (!req.body.password) {
return res.status(401)
.send({
status: false,
message: "Password field cannot be empty"
});
}
return User.findOne({
where: {
username,
}
})
.then((user) =>{
if(!user) {
return res.status(401).send({message: "User is not registered"})
}
else if(!user.validPassword(req.body.password)){
return res.status(401)
.send({
message: "The password is incorrect"
})
}
const token = user.generateAuthToken();
res.header('x-auth', token).status(200).send({
statusCode: 200,
message: `Welcome back, ${user.username}`,
user
});
})
.catch(error => {return res.status(400).send(error)})
},
这是我得到的错误:
1) Testing API routes POST /api/users/ it should signin a new user:
Error: expected 200 "OK", got 401 "Unauthorized"
at Test._assertStatus (node_modules\supertest\lib\test.js:266:12)
at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
at Test.assert (node_modules\supertest\lib\test.js:171:18)
at Server.assert (node_modules\supertest\lib\test.js:131:12)
at emitCloseNT (net.js:1552:8)
at _combinedTickCallback (internal/process/next_tick.js:77:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
答案 0 :(得分:0)
我会在那里放一堆console.log()
来确切知道哪些代码正在解雇,因为你有4次机会解雇401.
以下是一些供您检查的代码:
// I don't understand enough context, so I have to re-write this
// to show you how it could be an async function which will
// return a promise, but will also allow you to await.
// async function sign(req, res) {
const sign = async (req, res) => { // This is same as above line
const username = req.body.username.toLowerCase().trim();
// const email = req.body.email.trim();
if (!username) {
console.log('username was empty')
return res.status(401).send({
status: false,
message: "Username cannot be empty"
});
}
if (!req.body.password) {
console.log('password was empty')
return res.status(401).send({
status: false,
message: "Password field cannot be empty"
});
}
return await User.findOne({ where: { username } })
// I'm making this one async also to ensure user.generateAuthToken()
// has a value before it proceeds to res.send()
.then(async (user) => {
if (!user) {
console.log('couldnt find user')
return res.status(401).send({
message: "User is not registered"
})
}
else if (!user.validPassword(req.body.password)){
console.log('password was incorrect')
return res.status(401).send({
message: "The password is incorrect"
})
}
const token = await user.generateAuthToken();
// I added a return here
return res.header('x-auth', token).status(200).send({
statusCode: 200,
message: `Welcome back, ${user.username}`,
user
});
})
.catch((error) => {
console.log('lets put data in here: ' + error)
return res.status(400).send(error)
})
},
我注意到MongoDB搜索
User.findOne({ where: { username } })
。我无法记住它是否需要$where
。我认为MongoDB语法使用$。这可能是你的问题,如果是的话,它会触发console.log('couldnt find user')
。这可能只适用于本机MongoDB驱动程序。我刚用谷歌搜索,发现语法也可以是:User.findOne({ username })
,这是User.findOne({ username: username })
的简写。
有些人会告诉你执行return await fn()
并省略await
是多余的,但如果承诺被拒绝,它会抛出未处理的承诺拒绝。如果有等待,它将被捕获。这是高端范围的错误处理架构的一部分。
我建议观看一些async / await教程,因为我看到你混合了一点回调酱。你的代码非常好,但我认为你可以将它提升到一个新的水平。看起来你已经准备好了。
有趣的是,如果您的{
语句只有一个表达式,您也可以省略}
和if
,即:
if (err) {
throw err;
}
可以是速记:
if (err) throw err;
这可以帮助清理代码,但是使用与throw
一起正确使用的try / catch块的async / await语法将对嵌入最少的同步代码进行令人难以置信的改进。
以下是您可以重新编写其中一些内容的方法,因为我想向您展示如何摆脱嵌套,这会增加流量控制的混乱:
const sign = async (req, res) => {
try {
const username = req.body.username.toLowerCase().trim()
if (!username) throw 'noUsername'
if (!req.body.password) throw 'noPassword'
const foundUser = await User.findOne({ username })
if (!foundUser.username) throw 'notFound'
// I assume this returns Boolean
const validPassword = await user.validPassword(req.body.password)
if (!validPassword) throw 'invalidPassword'
// Alter generateAuthToken() to throw 'badToken' if it fails
const token = await user.generateAuthToken()
return res.header('x-auth', token).status(200).send({
statusCode: 200,
message: `Welcome back, ${user.username}`,
user
})
} catch (error) {
// errors are manually thrown into here, and rejected promises
// are automatically thrown into here
if (error === 'noUsername') return res.status(401).send({
status: false,
message: 'Username cannot be empty'
})
if (error === 'noPassword') return res.status(401).send({
status: false,
message: 'Password field cannot be empty'
})
if (error === 'notFound') return res.status(401).send({
message: 'User is not registered'
})
if (error === 'invalidPassword') return res.status(401).send({
message: 'The password is incorrect'
})
if (error === 'badToken') return res.status(403).send({
message: 'User is not authorized'
})
return res.status(400).send(error)
}
}
sign(req, res).then((response) => console.log(response))
希望这对我有帮助:)抱歉我不使用分号。