Mocha / Chia测试在通过/失败测试之前不等待方法链完成

时间:2019-02-22 21:30:27

标签: testing mocha chai

所以我现在已经在我的这个项目上工作了一段时间,但是我永远无法真正弄清楚如何使我的测试生效。我尝试过以各种不同的方式测试我的API,但是每次更改内容时,似乎只会遇到更多问题。在这一点上,我很沮丧,我需要一些新鲜的眼睛来检查一下。

仅供参考,API实际上可以正常工作,我可以调用所有路由并毫无问题地获得正确的结果,我一直在使用httpie来进行“测试”,而无需实际编写任何测试。

无论如何,这是我一直在运行的一些代码:

const chai = require('chai');
const expect = chai.expect;
const superagent = require('superagent');

const User = require('../model/User.js');

const url = process.env.API_URL;

const testUser = {
  email: 'exampleuser@test.com',
  password: '123'
};

const newUser = {
  email: 'newuser@test.com',
  password: '321'
};

describe('POST: /api/signup', () => {
  describe('with valid credentials', () => {
    afterEach(() => User.deleteOne({'email': testUser.email}));

    console.log(`${url}/api/signup`);
    it('should return a status code of 200', () => {
      superagent.post(`${url}/api/signup`)
        .send(testUser)
        .then((res) => {
          expect(res).to.be.an('object');
          expect(res.status).to.equal(200);
        })
        .catch((err) => console.error(err));
    });
  });
});

我也尝试使用done,它看起来像这样:

describe('POST: /api/signup', () => {
  describe('with valid credentials', () => {
    afterEach((done) => {
      User.deleteOne({'email': testUser.email})
        .then(() => done())
        .catch((err) => done(err));
    });

    console.log(`${url}/api/signup`);
    it('should return a status code of 200', (done) => {
      superagent.post(`${url}/api/signup`)
        .send(testUser)
        .end((res, err) => {
          if(err) return done(err);
          expect(res).to.be.an('object');
          expect(res.status).to.equal(200);
        })
        .then(() => done())
        .catch((err) => console.error(err));
    });
  });
});

但是每次我运行它时,您都可以看到它完成了测试并转到下一个情况,然后调用并返回所有内容:

Backend-Portfolio:server.js running on port: 8000 +0ms

  USER_ROUTES
    POST: /api/signup
      with valid credentials
        1) should return a status code of 200
  Backend-Portfolio:user-router.js POST: /api/signup +0ms
        2) "after each" hook for "should return a status code of 200"
    GET: /api/login
      with valid credentials
  Backend-Portfolio:user-router.js POST: /api/signup +2s
  Backend-Portfolio:user-router.js setting up new user +50ms
  Backend-Portfolio:User.js generatePasswordHash:normal +0ms
  Backend-Portfolio:User.js generateToken +158ms
  Backend-Portfolio:User.js generateFindHash +1ms
  Backend-Portfolio:user-router.js setting up new user +462ms
  Backend-Portfolio:User.js generatePasswordHash:normal +295ms
  Backend-Portfolio:User.js generateToken +101ms
  Backend-Portfolio:User.js generateFindHash +0ms

如果有人好奇,这里是路线和调用的方法:

您可以在这里看到方法链的调用位置,我将这条路线变成了一个承诺,只是尝试使用另一种测试方法。

userRouter.post('/api/signup', jsonParser, (req, res) => {
  debug('POST: /api/signup');

  let password = req.body.password;
  delete req.body.password;

  return new Promise((resolve, reject) => {
    User.findOne({'email': req.body.email})
      .then((user) => {
        if(user){
          if(user.authenticated){
            // NOTE: maybe update all error codes and texts to be very specific
            reject(createError(400, 'this email is already used, please log in with your password'));
          }else{
            user.generatePasswordHash('normal', password)
              .then((user) => user.generateToken())
              .then((token) => resolve(res.json(token)))
              .catch((err) => reject(console.error(err)));
          }
        }
        else{
          debug('setting up new user');
          let user = new User({
            googlePermissions: {authenticated: false, password: null},
            facebookPermissions: {authenticated: false, password: null},
            twitterPermissions: {authenticated: false, password: null},
            authenticated: true,
            email: req.body.email
          });

          user.generatePasswordHash('normal', password)
            .then((user) => user.generateToken())
            .then((token) => resolve(res.json(token)))
            .catch((err) => reject(console.error(err)));
        }
      })
      .catch((err) => reject(console.error(err)));
  });
});

剩下的事情可能有点多余,但是可以了:

generatePasswordHash:

userSchema.methods.generatePasswordHash = function(type, password){
  debug(`generatePasswordHash:${type}`);

  return new Promise((resolve, reject) => {
    if(!password) reject(createError(400, 'no password was provided'));

    bcrypt.hash(password, 10, (err, hash) => {
      if(err) return reject(err);
      switch(type){
      case 'normal':
        this.password = hash;
        resolve(this);
        break;
      case 'googlePermissions':
        this.googlePermissions.password = hash;
        resolve(this);
        break;
      case 'facebookPermissions':
        this.facebookPermissions.password = hash;
        resolve(this);
        break;
      case 'twitterPermissions':
        this.twitterPermissions.password = hash;
        resolve(this);
        break;
      default:
        return reject(createError(400, `unrecognized password type: ${type}`));
      }
    });
  });
};

generateToken:

userSchema.methods.generateToken = function(){
  debug('generateToken');

  return new Promise((resolve, reject) => {
    this.generateFindHash()
      .then((findHash) => resolve(jsonwebtoken.sign({token: findHash}, process.env.APP_SECRET)))
      .catch((err) => reject(err));
  });
};

generateFindHash:

userSchema.methods.generateFindHash = function(){
  debug('generateFindHash');

  return new Promise((resolve, reject) => {
    this.findHash = crypto.randomBytes(32).toString('hex');
    this.save()
      .then(() => resolve(this.findHash))
      .catch((err) => reject(err));
  });
};

感谢到目前为止取得成功的任何人。

0 个答案:

没有答案