title: How to mock ES6 super class and spy on it with jest.js?
body: <p>I have a class <code>Qux</code> that inherits from class <code>Baa</code> and I would like to mock <code>Baa</code> while testing <code>Qux</code>. That works in principle if I don't try to spy on the mock <code>BaaMock</code>.</p>
  <p>If I would like to spy on the mocked class, the <a href="https://jestjs.io/docs/en/es6-class-mocks" rel="nofollow noreferrer">doc</a> says that I should use a jest.fn() instead of the class. However, that does not seem to work correctly: some of the methods of the inheriting class <code>Qux</code> are lost.</p>
  <p>Some example code (also available at <a href="https://github.com/stefaneidelloth/testDemoES6Jest" rel="nofollow noreferrer">https://github.com/stefaneidelloth/testDemoES6Jest</a>) :</p>
  <p>Super class Baa (/src/baa.js):</p>
  <pre><code>import Foo from './foo.js';
  
  export default class Baa extends Foo {
      
      constructor(name){
          super(name);    
      }
      
      baaMethod(){
          return 'baaMethod';
      }
      
      overridableMethod() {
          return 'baa';
      }
  }
  </code></pre>
  <hr />
  <p>Inheriting class Qux (/src/qux.js):</p>
  <pre><code>import Baa from './baa.js';
  
  export default class Qux extends Baa {
      
      constructor(name){
          super(name);        
      }
      
      quxMethod(){
          return 'quxMethod';
      }
      
      overridableMethod() {
          return 'qux';
      }
  }
  </code></pre>
  <hr />
  <p><strong>A.</strong> Test for inheriting class Qux without a possibility to spy (/test/qux.test.js):</p>
  <pre><code>jest.mock('./../src/baa.js', () =&gt; {
      return class BaaMock {
          constructor(name){
              this.name = name;
          }
  
          baaMethod(){
              return 'baaMockedMethod';
          }
      }   
  });
  
  import Qux from './../src/qux.js';
  
  describe('Qux', function(){
  
      var sut;        
  
      beforeEach(function(){          
          sut = new Qux('qux');       
      });
  
      it('quxMethod', function(){         
          expect(sut.quxMethod()).toEqual('quxMethod');
      }); 
  
      it('baaMethod', function(){         
          expect(sut.baaMethod()).toEqual('baaMockedMethod');
      }); 
  
      it('overridableMethod', function(){         
          expect(sut.overridableMethod()).toEqual('qux');
      });         
  
  }); 
  </code></pre>
  <hr />
  <p><strong>B.</strong> In order to be able to spy on the mocked class, I tried to replace the class with a mock function (also see <a href="https://jestjs.io/docs/en/es6-class-mocks" rel="nofollow noreferrer">https://jestjs.io/docs/en/es6-class-mocks</a>):</p>
  <pre><code>import Baa from './../src/baa.js';
  jest.mock('./../src/baa.js', 
      function(){
          return jest.fn().mockImplementation(
              function(name){
                  return {
                      name:name,
                      baaMethod: () =&gt;{ return 'baaMockedMethod';}
                  };
              }
          );
      }
  );
  
  import Qux from './../src/qux.js';
  
  describe('Qux', function(){
  
      var sut;        
  
      beforeEach(function(){
          
          //Baa.mockClear();
          sut = new Qux('qux');           
          //expect(Baa).toHaveBeenCalledTimes(1);
      });
  
      it('quxMethod', function(){         
          expect(sut.quxMethod()).toEqual('quxMethod');
      }); 
  
      it('baaMethod', function(){         
          expect(sut.baaMethod()).toEqual('baaMockedMethod');
      }); 
  
      it('overridableMethod', function(){         
          expect(sut.overridableMethod()).toEqual('qux');
      });         
  
  }); 
  </code></pre>
  <p>As a result, the <strong>test fails with following errors</strong>:</p>
  <pre><code>FAIL test/qux.test.js
  
    Qux
      × quxMethod (7ms)
      √ baaMethod (4ms)
      × overridableMethod (2ms)
  
    ● Qux › quxMethod
  
      TypeError: sut.quxMethod is not a function
  
        28 | 
        29 |  it('quxMethod', function(){         
      &gt; 30 |      expect(sut.quxMethod()).toEqual('quxMethod');
           |                 ^
        31 |  }); 
        32 | 
        33 |  it('baaMethod', function(){         
  
        at Object.quxMethod (test/qux.test.js:30:14)
  
    ● Qux › overridableMethod
  
      TypeError: sut.overridableMethod is not a function
  
        36 | 
        37 |  it('overridableMethod', function(){         
      &gt; 38 |      expect(sut.overridableMethod()).toEqual('qux');
           |                 ^
        39 |  });         
        40 | 
        41 | });  
  
        at Object.overridableMethod (test/qux.test.js:38:14)
  </code></pre>
  <p>I would expect my instance <code>sut</code> of <code>Qux</code> to still contain the methods <code>quxMethod</code>  and <code>overridableMethod</code>  that are defined by the class Qux.</p>
  <p><strong>=&gt;</strong> Is this a bug of jest?</p>
  <p><strong>=&gt;</strong> If not, why should do I need to implement all methods of Qux in the mock for Baa !!???</p>
  <p><strong>=&gt;</strong> How do I need to adapt my example code <strong>B</strong> do successfully mock the class Baa, so that Qux is still able to inherit from it?</p>