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