Ren*_*nis 8 javascript testing unit-testing node.js sinon
新的单元测试和间谍,存根和嘲笑的概念.
我想从下面的代码中测试该verify方法password.js,但我无法在测试文件中使用stub该hash函数.
由于verify采用了hash功能和hash性能输出,不过,我觉得我应该stub在hash函数返回,而实际调用一个固定的响应hash.因为我不是想测试这个hash功能.
问题:hash测试时未调用创建的函数存根verify.
问题1:我应该专注于测试函数本身的逻辑而不是其他被称为函数的逻辑吗?
主要问题:(已 回答)如何在同一模块中调用模块函数?
问题2: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};
Run Code Online (Sandbox Code Playgroud)
password.test.js
import test from 'ava';
import sinon from 'sinon';
import passwordModule from './password';
test('verify - should verify password', function * (t) {
const password = 'test-password';
const salt = null;
const hash = 'my-hash';
const hashStub = sinon.stub(passwordModule, 'hash', (password, salt) => Promise.resolve({hash, salt}));
const verified = yield passwordModule.verify(password, hash, salt);
t.true(verified);
hashStub.restore();
});
Run Code Online (Sandbox Code Playgroud)
测试和模块用babel进行.但是该模块没有使用ES6模块导出,因为它在节点env中使用而没有进行转换.
我正在测试期间发布所有代码,以便它是未来的证明,并且save env可以用于前端代码和后端代码,前端代码在其中被传输.
问题1:我应该专注于测试函数本身的逻辑而不是其他被称为函数的逻辑吗?
测试的一部分verify是确保它hash正确调用.同样在更一般的意义上,并不是那么适用于您的代码,是一个函数应该正确处理其他函数抛出的错误.在您的情况下,您将任何错误传播给调用者verify,这就是它不适用的原因.
主要问题:如何在同一模块中调用模块函数?
您已经找到了答案,但请参阅下面的替代方案.
方面问题2:如果没有导出但仅保留在模块内,我将如何进行存根哈希?
一个很棒的模块是rewire,它允许您覆盖模块内的私有(非导出)变量.它也有助于你的"主要问题",因为它允许你像以前一样保留代码.
这是你对重新布线的测试:
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();
});
Run Code Online (Sandbox Code Playgroud)
找到了 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);
}
Run Code Online (Sandbox Code Playgroud)
还是想知道附带问题的答案。