Home > Mobile >  Mock instantiated class method with a different return value in each test
Mock instantiated class method with a different return value in each test

Time:08-10

I'm trying to test my code, which uses a third party library ssh2-promise, with jest. ssh2-promise is used by instantiating an instance of a class, and using methods of this instance. I use the same instance method in each of "my module"'s functions I want to test.

How do I mock the return value of the instance's exec method differently for each test?

// my-module

const SSH2Promise = require('ssh2-promise');
const ssh = new SSH2Promise({});
    
const methodA = (params) => {
   ssh.connect();
   const results = await ssh.exec(/* some command */);
   ssh.close();
   return results;
}

const methodB = (params) => {
   ssh.connect();
   const results = await ssh.exec(/* some other command */);
   ssh.close();
   return results;
}
    
module.exports = { methodA, methodB };

// Test attempt

const SSH2Promise = require('ssh2-promise');
jest.mock('ssh2-promise');
const myModule = require('./my-module');
    
describe('my module', () => {
  beforeEach(() => {
    // Clear all instances and calls to constructor and all methods:
    SSH2Promise.mockClear();        
  });

  test('methodA', () => {
    const expected = 'A results';
    SSH2Promise.mockImplementation(() => ({
      connect: () => {},
      close: () => {},
      exec: () => Promise.resolve(expected),
    }));
    const promise = myModule.methodA();
    expect(promise).resolves.toEqual(expected);
    expect(SSH2Promise).toHaveBeenCalled();
  });

  test('methodA', () => {
    const expected = 'B results';
    SSH2Promise.mockImplementation(() => ({...});
    // etc...
  });
});

When exec is called in methodA during the test, the results are undefined. Inspecting, I see this, so it's not using my implementation.

console.log(ssh.exec)
ƒ exec() {return mockConstructor.apply(this,arguments);}

How do I make this work?

CodePudding user response:

This is how I resolved:

const myModule = require('./my-module');
const SSH2Promise = require('ssh2-promise');
jest.mock('ssh2-promise');
    
describe('my module', () => {
    
  test('methodA', () => {
     const expected = 'A results';
     SSH2Promise.prototype.exec.mockImplementation(() => Promise.resolve(expected));
     const promise = myModule.methodA();
     expect(promise).resolves.toEqual(expected);
     expect(SSH2Promise.prototype.exec).toHaveBeenCalled();
   });

   test('methodA', () => {
     const expected = 'B results';
      SSH2Promise.prototype.exec.mockImplementation(() => Promise.resolve(expected));
     // etc...
   });
});
  • Related