模拟在同一模块中导出和调用的模块函数?

时间:2016-06-07 18:24:26

标签: javascript node.js unit-testing testing sinon

新的单元测试以及间谍,存根和模拟的概念。

我想从下面的代码中测试来自verify的{​​{1}}方法,但我无法password.js测试文件中的stub函数。< / p>

由于hash使用了verify函数并导出了hash函数,但我应该hash stub函数返回固定响应实际调用hash。因为我没有尝试测试hash功能。

问题:测试hash时,未调用hash函数的已创建存根。

问题1:我应该专注于测试函数本身的逻辑而不是其他调用函数吗?

主要问题: (已回答)如何在同一模块中调用模块函数?

问题2:如果verify未导出但仅保留在模块中,我该怎么做呢?

代码

hash

password.js

/** * Creates a hash based on a salt from a given password * if there is no salt a new salt will be generated * * @param {String} password * @param {String} [salt] Optional value, if not given will generate a salt */ function hash (password, salt) { // returns a promise that resolves an hash object with hash and salt key // example: {hash: '2512521nska...', salt: '25hbBhhsfa...'} } /** * Verifies if a password matches a hash by hashing the password * with a given salt * * @param {String} password * @param {String} hashString * @param {String} salt */ function verify (password, hashString, salt) { return hash(password, salt) .then((res) => res.hash === hashString); } module.exports = {hash, verify};

password.test.js

设置

  • Node v6.2.0
  • Ava v0.15.2
  • 兴农&#34; v1.17.4
  

测试和模块是用babel进行的。但是模块没有使用ES6模块导出,因为它在节点env中使用而没有进行转换。   
我在测试期间发布所有代码,以便将来证明,并且save env可以用于前端代码和后端代码,前端代码被传输。

2 个答案:

答案 0 :(得分:7)

  

问题1:我应该专注于测试函数本身的逻辑而不是其他调用函数吗?

部分测试verify确保正确调用hash。同样在更一般的意义上,并不是那么适用于您的代码,是一个函数应该正确处理其他函数抛出的错误。在您的情况下,您将任何错误传播给verify的来电者,这就是为什么它并不真正适用。

  

主要问题:如何在同一模块中调用模块函数?

您已经找到了答案,但请参阅下面的替代方案。

  

问题2:如果哈希未导出但仅保留在模块中,我将如何进行存根哈希?

一个很棒的模块是rewire,它允许您覆盖模块内的私有(非导出)变量。它还有助于您的主要问题&#34;,因为它允许您像以前一样保留代码。

这是你重新接线的测试:

import test   from 'ava';
import sinon  from 'sinon';
import rewire from 'rewire';

const passwordModule = rewire('./password');

test('verify - should verify password', function * (t) {
  const password = 'test-password';
  const salt = null;
  const hash = 'my-hash';

  let hashStub = sinon.stub().returns(Promise.resolve({hash, salt}));

  // Replace the `hash` function inside your module with the stub.
  let revert   = passwordModule.__set__('hash', hashStub);

  const verified = yield passwordModule.verify(password, hash, salt);

  t.true(verified);

  // Revert to the original `hash` function.
  revert();
});

答案 1 :(得分:2)

在stackoverflow中找到主要问题的答案:
Stub module function called from the same module

要解决此问题,我需要将哈希导出为hash函数,而不是私有。

exports.hash = function hash (password, salt) {
  // returns a promise that resolves an hash object with hash and salt key
  // example: {hash: '2512521nska...', salt: '25hbBhhsfa...'}
}

exports.verify = function verify (password, hashString, salt) {
  return exports.hash(password, salt)
    .then((res) => res.hash === hashString);
}

仍然想知道旁边问题的答案。