title: How to change mock implementation on a per single test basis?
body: <p>I'd like to change the implementation of a mocked dependency on a per single test basis by extending the default mock's behaviour and reverting it back to the original implementation when the next test executes.</p>
  <p>More briefly, this is what I'm trying to achieve:</p>
  <ol>
  <li>Mock dependency</li>
  <li>Change/extend mock implementation in a single test</li>
  <li>Revert back to original mock when next test executes</li>
  </ol>
  <p>I'm currently using Jest v21. Here is what a typical test would look like:</p>
  <pre><code>// __mocks__/myModule.js
  
  const myMockedModule = jest.genMockFromModule('../myModule');
  
  myMockedModule.a = jest.fn(() =&gt; true);
  myMockedModule.b = jest.fn(() =&gt; true);
  
  export default myMockedModule;
  </code></pre>
  <pre><code>// __tests__/myTest.js
  
  import myMockedModule from '../myModule';
  
  // Mock myModule
  jest.mock('../myModule');
  
  beforeEach(() =&gt; {
    jest.clearAllMocks();
  });
  
  describe('MyTest', () =&gt; {
    it('should test with default mock', () =&gt; {
      myMockedModule.a(); // === true
      myMockedModule.b(); // === true
    });
  
    it('should override myMockedModule.b mock result (and leave the other methods untouched)', () =&gt; {
      // Extend change mock
      myMockedModule.a(); // === true
      myMockedModule.b(); // === 'overridden'
      // Restore mock to original implementation with no side effects
    });
  
    it('should revert back to default myMockedModule mock', () =&gt; {
      myMockedModule.a(); // === true
      myMockedModule.b(); // === true
    });
  });
  </code></pre>
  <p>Here is what I've tried so far:</p>
  <ol>
  <li><p><a href="https://facebook.github.io/jest/docs/en/mock-function-api.html#mockfnmockimplementationoncefn" rel="noreferrer"><code>mockFn.mockImplementationOnce(fn)</code></a></p>
  <pre><code>it('should override myModule.b mock result (and leave the other methods untouched)', () =&gt; {
  
    myMockedModule.b.mockImplementationOnce(() =&gt; 'overridden');
  
    myModule.a(); // === true
    myModule.b(); // === 'overridden'
  });
  </code></pre>
  <p><strong>Pros</strong></p>
  <ul>
  <li>Reverts back to original implementation after first call</li>
  </ul>
  <p><strong>Cons</strong></p>
  <ul>
  <li>It breaks if the test calls <code>b</code> multiple times</li>
  <li>It doesn't revert to original implementation until <code>b</code> is not called (leaking out in the next test)</li>
  </ul>
  </li>
  <li><p><a href="https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options" rel="noreferrer"><code>jest.doMock(moduleName, factory, options)</code></a></p>
  <pre><code>it('should override myModule.b mock result (and leave the other methods untouched)', () =&gt; {
  
    jest.doMock('../myModule', () =&gt; {
      return {
        a: jest.fn(() =&gt; true,
        b: jest.fn(() =&gt; 'overridden',
      }
    });
  
    myModule.a(); // === true
    myModule.b(); // === 'overridden'
  });
  </code></pre>
  <p><strong>Pros</strong></p>
  <ul>
  <li>Explicitly re-mocks on every test</li>
  </ul>
  <p><strong>Cons</strong></p>
  <ul>
  <li>Cannot define default mock implementation for all tests</li>
  <li>Cannot extend default implementation forcing to re-declare each mocked method</li>
  </ul>
  </li>
  <li><p>Manual mocking with setter methods (as explained <a href="https://facebook.github.io/jest/docs/en/manual-mocks.html#docsNav" rel="noreferrer">here</a>)</p>
  <pre><code>// __mocks__/myModule.js
  
  const myMockedModule = jest.genMockFromModule('../myModule');
  
  let a = true;
  let b = true;
  
  myMockedModule.a = jest.fn(() =&gt; a);
  myMockedModule.b = jest.fn(() =&gt; b);
  
  myMockedModule.__setA = (value) =&gt; { a = value };
  myMockedModule.__setB = (value) =&gt; { b = value };
  myMockedModule.__reset = () =&gt; {
    a = true;
    b = true;
  };
  export default myMockedModule;
  </code></pre>
  <pre><code>// __tests__/myTest.js
  
  it('should override myModule.b mock result (and leave the other methods untouched)', () =&gt; {
    myModule.__setB('overridden');
  
    myModule.a(); // === true
    myModule.b(); // === 'overridden'
  
    myModule.__reset();
  });
  </code></pre>
  <p><strong>Pros</strong></p>
  <ul>
  <li>Full control over mocked results</li>
  </ul>
  <p><strong>Cons</strong></p>
  <ul>
  <li>Lot of boilerplate code</li>
  <li>Hard to maintain on long term</li>
  </ul>
  </li>
  <li><p><a href="https://facebook.github.io/jest/docs/en/jest-object.html#jestspyonobject-methodname" rel="noreferrer"><code>jest.spyOn(object, methodName)</code></a></p>
  <pre><code>beforeEach(() =&gt; {
    jest.clearAllMocks();
    jest.restoreAllMocks();
  });
  
  // Mock myModule
  jest.mock('../myModule');
  
  it('should override myModule.b mock result (and leave the other methods untouched)', () =&gt; {
  
    const spy = jest.spyOn(myMockedModule, 'b').mockImplementation(() =&gt; 'overridden');
  
    myMockedModule.a(); // === true
    myMockedModule.b(); // === 'overridden'
  
    // How to get back to original mocked value?
  });
  </code></pre>
  <p><strong>Cons</strong></p>
  <ul>
  <li>I can't revert <code>mockImplementation</code> back to the original mocked return value, therefore affecting the next tests</li>
  </ul>
  </li>
  </ol>