Flushing a module function that is exported and called in one module?

new for unit testing and the concept of spies, stubs and layouts.

I want to test the verify method from password.js from the code below, but I cannot stub use the hash function in the test file.

Since verify uses the hash function, and the hash function is exported, I have to stub use the hash function to return a fixed response, rather than actually calling hash . Since I am not trying to test the hash function.

Problem: The created stub for the hash function is not called when testing verify .

Side question 1: Should I focus on checking the logic of the function itself, and not on other called functions?

The main question: (answers) How to drown out a module function that is called in the same module?

Side question 2:. How can I perform stubbing hash if it is not exported, but remains only inside the module?

the code

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

 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(); }); 

Customization

  • Node v6.2.0
  • Ava v0.15.2
  • Sinon "v1.17.4

Tests and modules are broadcast using babel. But the module does not use the export of ES6 modules, as it is used in node env without forwarding.
I translate all the code during testing so that it becomes a future proof, and env preservation can be used both for the external interface and for the backend code, where the translation code is full.

+6
source share
2 answers

Found the answer for the main question in stackoverflow:
Dummy module function called from the same module

To fix the problem, I needed to call the hash with the exported hash function, not the private one.

 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); } 

Still would like to know the answers to the questions.

+1
source

Side question 1: Should I focus on checking the logic of the function itself, and not on other called functions?

The verify testing verify verifies that the hash call is correct. In addition, in a more general sense and not so much applicable to your code, that a function should handle errors caused by other functions. In your case, you are distributing any errors to verify , so it does not apply.

The main question: How to drown out a module function called inside the same module?

You have already found the answer, but see the alternative below.

Side question 2:. How can I use a hash stub if it is not exported, but remains only inside the module?

A great module for this rewire , which allows you to overwrite private (unexported) variables inside the module. This will also help with your โ€œcore questionโ€, as it allows you to leave the code as before.

Here is your rewire test:

 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(); }); 
+5
source

All Articles