mardi 7 juin 2016

Mocking a module function which is exported and called within the same module?

new to unit testing and the concepts of spies, stubs and mocks.

I want to test the verify method from password.js from code below, but I'm unable to stub the hash function within the test file.

As verify uses the hash function and the hash function is exported, I though I should stub the hash function to return a fixed response rather the actually calling hash. As I'm not trying to test the hashfunction.

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

Side question 1: Should I be focusing on testing the logic of the function itself rather the other called functions?

Main Question: How do stub a module function that is called within the same module?

Side question 2: How would I go about stubbing hash if it where not exported but stayed only within the module?

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

Setup

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

Tests and the modules are transpilled with babel. But the module isn't using ES6 module exports as it is used in node env without transpilling.
I'm transpilling all code during testing so that it is future proof and the save env can be used for both frontend and backend code, where the frontend code is transpilled.

Aucun commentaire:

Enregistrer un commentaire