Javascript - 在测试期间提供错误的状态代码

时间:2017-09-08 20:04:14

标签: javascript node.js mocha

我正在运行登录控制器的测试,它一直给出错误的状态代码(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)

1 个答案:

答案 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))

希望这对我有帮助:)抱歉我不使用分号。