Jest - 'child_process' 包中的模拟函数

Dav*_*aiz 6 unit-testing jestjs

我正在编写单元测试并模拟包“child_process”中的“exec”方法。

__mocks__/child_process.js

const child_process = jest.genMockFromModule('child_process');
child_process.exec = jest.fn()

module.exports = child_process;
Run Code Online (Sandbox Code Playgroud)

这是测试文件:

const fs = require('fs-extra'),
      child_process = require('child_process'),
      runCassandraMigration = require('../../lib/runCassandraMigration.js')

const defaultArguments = () => {
  return {
    migration_script_path: './home',
    logger: {
      error: function () {}
    }
  };
}

jest.mock("fs-extra")
jest.mock("child_process")

describe('Running cassandra migration tests', function () {
  describe('successful flow', function () {
    it('Should pass without any errors ', async function () {
        let args = defaultArguments();
        let loggerSpy = jest.spyOn(args.logger, 'error')

        fs.remove.mockImplementation(() => {Promise.resolve()})
        child_process.exec.mockImplementation(() => {Promise.resolve()})

        await runCassandraMigration(args.migration_script_path, args.logger)
    });
  });
Run Code Online (Sandbox Code Playgroud)

当我运行测试时,我收到以下错误:

child_process.exec.mockImplementation is not a function
Run Code Online (Sandbox Code Playgroud)

我测试的模块

const fs = require('fs-extra')
const promisify = require('util').promisify
const execAsync = promisify(require('child_process').exec)

module.exports = async (migration_script_path, logger) => {
  try {
    console.log()
    const {stdout, stderr} = await execAsync(`cassandra-migration ${migration_script_path}`)
    logger.info({stdout: stdout, stderr: stderr}, 'Finished runing cassandra migration')
    await fs.remove(migration_script_path)
  } catch (e) {
    logger.error(e, 'Failed to run cassandra migration')
    throw Error()
  }
}
Run Code Online (Sandbox Code Playgroud)

请指教。

Dan*_*ñoz 8

迟到的回答?...

昨天我遇到了同样的错误,问题是我没有调用jest.mock('child_process')我的测试文件。

Jest文档说,当模拟 Node 的核心模块时,jest.mock('child_process')需要调用。我看到你这样做,但由于某种原因它不起作用(也许 Jest 没有将其提升到顶部)。

无论如何,在 Jest 版本 24.9.0 中,我没有收到child_process.exec.mockImplementation is not a function错误,但收到了一些其他错误,因为您的测试没有很好地实现。

为了让你的测试工作,我:

info: function () {},里面添加了logger

exec更新了to的实现child_process.exec.mockImplementation((command, callback) => callback(null, {stdout: 'ok'})) 并且(测试通过不需要)更新了fs.removeto的实现fs.remove.mockImplementation(() => Promise.resolve())

像这样:

const fs = require('fs-extra'),
      child_process = require('child_process'),
      runCassandraMigration = require('./stack')

const defaultArguments = () => {
  return {
    migration_script_path: './home',
    logger: {
      info: function () {},
      error: function () {}
    }
  };
}

jest.mock("fs-extra")
jest.mock("child_process")

describe('Running cassandra migration tests', function () {
  describe('successful flow', function () {
    it('Should pass without any errors ', async function () {
        let args = defaultArguments();
        let loggerSpy = jest.spyOn(args.logger, 'error')

        fs.remove.mockImplementation(() => Promise.resolve())
        child_process.exec.mockImplementation((command, callback) => callback(null, {stdout: 'ok'}))

        await runCassandraMigration(args.migration_script_path, args.logger)
    });
  });
});
Run Code Online (Sandbox Code Playgroud)