Как проверить функцию слушателя внутри события выхода childporcess.on - PullRequest
0 голосов
/ 02 мая 2020

Я не могу увеличить тестовое покрытие / тестовую функцию, которая вызывается дочерним процессом при выходе. И я хочу смоделировать fork ('src / services / ssyn c -process. js');

log.info ('Дочерний процесс sProcessJob завершил выполнение'); sProcess.kill ();

никогда не покрываются

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

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

1 Ответ

1 голос
/ 02 мая 2020

Вот решение для модульного тестирования с использованием Link Seams , proxyquire пакета и rewire пакета.

Например,

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 |                   
----------|---------|----------|---------|---------|-------------------
...