title: Mocking a module function which is exported and called within the same module?
body: <p>new to unit testing and the concepts of spies, stubs and mocks.</p>
  
  <p>I want to test the <code>verify</code> method from <code>password.js</code> from code below, but I'm unable to <code>stub</code> the <code>hash</code> function within the test file.</p>
  
  <p>As <code>verify</code> uses the <code>hash</code> function and the <code>hash</code> function is exported, I though I should <code>stub</code> the <code>hash</code> function to return a fixed response rather the actually calling <code>hash</code>. As I'm not trying to test the <code>hash</code>function.</p>
  
  <p><strong>Problem:</strong> The created stub for <code>hash</code> function is not called when testing <code>verify</code>.</p>
  
  <p><strong>Side question 1:</strong> Should I be focusing on testing the logic of the function itself rather the other called functions?</p>
  
  <p><strong>Main Question:</strong> <em>(answered)</em> How do stub a module function that is called within the same module?</p>
  
  <p><strong>Side question 2:</strong> How would I go about stubbing <code>hash</code> if it where not exported but stayed only within the module?</p>
  
  <h2>Code</h2>
  
  <p><code>password.js</code></p>
  
  <pre><code>/**
   * 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) =&gt; res.hash === hashString);
  }
  
  module.exports = {hash, verify};
  </code></pre>
  
  <p><code>password.test.js</code></p>
  
  <pre><code>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) =&gt; Promise.resolve({hash, salt}));
  
    const verified = yield passwordModule.verify(password, hash, salt);
  
    t.true(verified);
  
    hashStub.restore();
  });
  </code></pre>
  
  <h2>Setup</h2>
  
  <ul>
  <li>Node v6.2.0</li>
  <li>Ava v0.15.2</li>
  <li>Sinon" v1.17.4</li>
  </ul>
  
  <blockquote>
    <p>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.
    <br>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.</p>
  </blockquote>