I have some typescript code that uses a promissified version of exec. I run it 3 times inside a method and want to spy on it to ensure the times called and that it has been called with the specific commands.
Here's what I have:
import { promisify } from 'util'
import { exec } from 'child_process';
const asyncExec = promisify(exec);
class SomeClass {
public async someFunction() {
await asyncExec('command 1');
await asyncExec('command 2');
await asyncExec('command 3');
}
}
When I didn't have the promissified version I had this Jest test and it worked.
import { SomeClass } from './SomeClass';
import * as cp from 'child_process';
const someClass = new SomeClass();
it('should execute all 3 commands', async () => {
const spyExec = spyOn(cp, 'exec');
await someClass.someFunction();
expect(spyExec).toHaveBeenCalledTimes(3);
expect(spyExec).toHaveBeenCalledWith('command 1')
expect(spyExec).toHaveBeenCalledWith('command 2')
expect(spyExec).toHaveBeenCalledWith('command 3')
})
But I can't find a way to make it work now that it is a promise. Does anyone have any suggestions?
The const asyncExec = promisify(exec);
function needs to be mocked, so instead of having it as a variable outside the class, you have to implement it as a public property in the class and then use the jest.spyOn()
method to spy on it.
In the class file it will look like this:
import { promisify } from 'util'
import { exec } from 'child_process';
class SomeClass {
public asyncExec = promisify(exec);
public async someFunction() {
await this.asyncExec('command 1');
await this.asyncExec('command 2');
await this.asyncExec('command 3');
}
}
The test will look like this:
import { SomeClass } from './SomeClass';
const someClass = new SomeClass();
it('should execute all 3 commands', async () => {
const spyExec = spyOn(someClass , 'asyncExec');
await someClass.someFunction();
expect(spyExec).toHaveBeenCalledTimes(3);
expect(spyExec).toHaveBeenCalledWith('command 1');
expect(spyExec).toHaveBeenCalledWith('command 2');
expect(spyExec).toHaveBeenCalledWith('command 3');
})