在 Node.js 中开玩笑监视 promisified 子进程

Jest spy on promisified child process in Node.js

我有一些使用 promisfied 版本的 exec 的打字稿代码。我 运行 它在一个方法中出现了 3 次,我想监视它以确保调用的次数以及它已使用特定命令调用。

这是我的:

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

当我没有承诺的版本时,我进行了这个 Jest 测试并且它起作用了。

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')
})

但我无法找到一种方法让它发挥作用,因为这是一个承诺。有人有什么建议吗?

const asyncExec = promisify(exec); 函数需要被模拟,所以与其将其作为 class 之外的变量,不如将其实现为 public 属性在 class 然后使用 jest.spyOn() 方法监视它。

在 class 文件中,它将如下所示:

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

测试将如下所示:

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