如何在childporcess.on退出事件中测试监听器功能?

问题描述 投票:0回答:1

我无法增加子进程在退出时调用的测试覆盖率测试函数,我想模拟fork('srcservicesssync-process.js')。

log.info('子进程sProcessJob完成执行');sProcess.kill()。

从未被覆盖

测试.js

const sinon = require('sinon');
const rewire = require('rewire');
const { EventEmitter } = require('events');
const job = rewire('../../src/services/job');

it('test exit', () => {
    const mockChildProcess = new EventEmitter();

    mockChildProcess.emit('exit');
    mockChildProcess.kill = sinon.stub();
    mockChildProcess.killed = true;
    job.__set__({
      sProcess: mockChildProcess,
    });

    job.sSyncJob();
  });

测试.js

const { fork } = require('child_process');

let sProcess;

const sSyncJob = () => {
  if (!sProcess || sProcess.killed) {
    sProcess = fork('src/services/ssync-process.js');
    sProcess.send({ hello: 'world' });
    sProcess.on('message', (msg) => {
      log.info('Message from child', msg);
    });
    sProcess.on('exit', () => {
      log.info('Child process sProcessJob finished execution');
      sProcess.kill();
    });
  }
};
node.js unit-testing sinon
1个回答
1
投票

下面是使用单元测试的解决方案 连接缝, 代理查询 包装和 重新布线 包。

例如

job.js:

let { fork } = require('child_process');

const log = {
  info: console.info,
};

let sProcess;

const sSyncJob = () => {
  if (!sProcess || sProcess.killed) {
    sProcess = fork('src/services/ssync-process.js');
    sProcess.send({ hello: 'world' });
    sProcess.on('message', (msg) => {
      log.info('Message from child', msg);
    });
    sProcess.on('exit', () => {
      log.info('Child process sProcessJob finished execution');
      sProcess.kill();
    });
  }
};

exports.sSyncJob = sSyncJob;

job.test.js:

const sinon = require('sinon');
const proxyquire = require('proxyquire');
const rewire = require('rewire');

describe('61561718', () => {
  afterEach(() => {
    sinon.restore();
  });
  it('should receive message', () => {
    const logSpy = sinon.spy(console, 'info');
    const child_process_fork_stub = {
      send: sinon.stub().returnsThis(),
      on: sinon
        .stub()
        .returnsThis()
        .yields('fake message'),
      kill: sinon.stub(),
    };
    const child_process_stub = {
      fork: sinon.stub().returns(child_process_fork_stub),
    };
    const job = proxyquire('./job', {
      child_process: child_process_stub,
    });
    job.sSyncJob();
    sinon.assert.calledWithExactly(child_process_stub.fork, 'src/services/ssync-process.js');
    sinon.assert.calledWithExactly(child_process_fork_stub.send, { hello: 'world' });
    sinon.assert.calledWithExactly(child_process_fork_stub.on, 'message', sinon.match.func);
    sinon.assert.calledWithExactly(child_process_fork_stub.on, 'exit', sinon.match.func);
    sinon.assert.calledWithExactly(logSpy, 'Message from child', 'fake message');
    sinon.assert.calledWithExactly(logSpy, 'Child process sProcessJob finished execution');
    sinon.assert.calledOnce(child_process_fork_stub.kill);
  });

  it('should not fork child process if sProcess exists', () => {
    const job = rewire('./job');
    const child_process_stub = {
      fork: sinon.stub(),
    };
    job.__set__({
      sProcess: {},
      child_process: child_process_stub,
    });
    job.sSyncJob();
    sinon.assert.notCalled(child_process_stub.fork);
  });
});

第一个测试用例使用 proxyquire 来测试,第二个测试用例使用 rewire 来测试。

单元测试结果,覆盖率100%。

  61561718
Message from child fake message
Child process sProcessJob finished execution
    ✓ should receive message
    ✓ should not fork child process if sProcess exists


  2 passing (52ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 job.js   |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
© www.soinside.com 2019 - 2024. All rights reserved.