Mocha 在测试 node.crypto 函数时抛出错误

Mocha throwing errors when testing node.crypto functions

我正在尝试测试我的密码散列函数,但由于某些 TypeError 错误,我总是失败。

我确信该函数有效,因为我尝试从其他文件调用它并且我得到了预期的结果而没有任何错误。

函数如下:

    exports.hashPassword = (password) => {
      return new Promise((resolve, reject) => {

        crypto.randomBytes(salt_length, (err, buf) => {
          if (err) reject(err);   

          const salt = buf.toString('base64');

          crypto.pbkdf2(password, salt, iterations, keylen, digest, (err, key) => {
            if (err) reject(err);

            const hashedPassword = '{X-PBKDF2}:'+digest+':'+keylenB64+':'+iterationsB64+':'+salt+':'+key.toString('base64');
            resolve(hashedPassword);
          });
        });
      });
    };

这是失败的测试:

    describe('users', () => {

      describe('utils', () => {

        it('should hash a password', (done) => {

          const password = 'secret';

          utils.hashPassword('secret')
          .then((hash) => {
            console.log('Hash: '+ hash);
            done();
          })
          .catch((err) => {
            console.log(err);
            done(err);
          });
        });
      });
    });

这是 'error':

1 failing

1) users utils should hash a password:
   TypeError: size must be a number >= 0
    at Promise (api\paths\users\utils.js:24:12)
    at Object.exports.hashPassword (api\paths\users\utils.js:14:10)
    at Context.it (api\paths\users\utils.test.js:30:13)

有人知道为什么吗?

我正在使用 mochashould 并在 node 上开发。

感谢 pietrovismara 让我找到了解决方案。

问题是 salt_length 是字符串而不是数字。我正在打印参数,我可以看到它们是 'correct' 但显然不是正确的类型(因此 TypeError,我猜......)

我将参数保存在 .env 文件中,并使用 dotenv 包读取它们,显然将它们读取为简单的字符串(应该如此)......这是为什么当我是 'testing' 时,来自另一个文件的函数是在那个实例中我没有使用从 .env 读取的参数,我有类似的东西:

const salt_length = process.env.SALT_LENGTH || 128;

Mocha 使用 .env 值(字符串)是正确的,但是在处理文件时我没有加载那些环境变量。

今天学到了一个道理,就是累了就回家,而不是继续充电,看不到眼前的东西。

此外,由于 mocha 支持承诺,'correct' 测试用例应该是(使用 should):

describe('users', () => {

    describe('utils', () => {

      it('should hash a password', () => {
        return utils.hashPassword('secret').should.be.fulfilled();
      });

    });
  });