Тестирование приложения Node.js, использующего Kue

Я хотел бы протестировать приложение, которое использует Kue, так что очередь заданий пуста перед каждым тестом и очищается после каждого теста. Очередь должна быть полностью функциональной, и мне нужно иметь возможность проверять состояние заданий, которые уже находятся в очереди.

Я пробовал mock-kue, и он работал хорошо, пока мне не пришлось получать задания из очереди и анализировать их. Я не мог заставить его вернуться на работу по идентификатору работы.

Ситуации, которые мне нужно проверить:

  1. Что-то происходит, и в очереди должна быть работа заданного типа,
  2. Что-то происходит и производит работу. Что-то еще происходит, и это задание удаляется и заменяется другим заданием (перепланирование или существующее задание).

Швы прямолинейны, но мне трудно обдумать проблему. Все указатели приветствуются.

2 ответа

Решение

По моему опыту, гораздо проще просто запустить redis на localhost везде, где вы хотите запустить свои тесты, вместо того, чтобы иметь дело с поддельной версией kue.

Во-первых, чтобы убедиться, что kue пуст перед каждым тестом, это может быть так же просто, как сброс redis, например:

var kue = require('kue');
var queue = kue.createQueue();

queue.client.flushdb(function(err) {});

Для #1 у kue есть метод rangeByType(), который должен решить вашу проблему:

var getJobs = function(type, state, cb) {
   kue.Job.rangeByType(type, state, 0, -1, 'asc', cb);    
}
// After something happens
getJobs('myJobType', 'active', function(err, jobs) {});

Для #2 вы можете использовать тот же метод и просто отслеживать идентификатор задания, чтобы знать, что он был заменен:

var jobId;
getJobs('myJobType', 'active', function(err, jobs) {
    assert.lengthOf(jobs, 1);
    jobId = jobs[0].id;
});

// After the thing happens
getJobs('myJobType', 'active' function(err, jobs) {
    assert.lengthOf(jobs, 1);
    assert.notEqual(jobId, jobs[0].id);
});

И если вам когда-нибудь понадобится запросить работу по ID, вы можете сделать это так:

kue.Job.get(jobId, function(err, job) {});

Взгляните на библиотеку kue-mock, она скорее для интеграционного тестирования, чем для unit.

Библиотека не взламывает внутренние компоненты kue (методы замены / переопределения и т. Д.). Вместо этого он создает исходный экземпляр очереди с отдельным пространством имен redis, а затем, при создании заглушки, на лету создает обработчики процессов работы, предоставляя свою собственную реализацию, которая дает вам возможность управлять поведением обработки работы.

Пример использования:

const expect = require('chai').expect;

const kue = require('kue');
const KueMock = require('kue-mock');
const $queue = new KueMock(kue);

const app = require('./your-app-file');

describe('functionality that deals with kue', () => {
  before(() => $queue.clean());
  afterEach(() => $queue.clean());

  it('enqueues a job providing some correct data', () => {
    let jobData;

    $queue.stub('your job type', (job, done) => {
      jobData = job.data;
      done();
    });

    return yourJobRunnerFunction()
      .then(() => {
        expect(jobData).to.be.an('object')
          .that.is.eql({ foo: 'bar' });
      });
  });

  describe('when the job is completed', () => {
    beforeEach(() => {
      $queue.stub('your job type')
        .yields(null, { baz: 'qux' });
    });

    it('correctly handles the result', () => {
      return yourJobRunnerFunction()
        .then((result) => {
          expect(result).to.eql({ baz: 'qux' });
        });
    });

    // ...
  });

  describe('when the job is failed', () => {
    beforeEach(() => {
      $queue.stub('your job type')
        .yields(new Error('Oops!'));
    });

    it('correctly handles the job result', () => {
      return yourJobRunnerFunction()
        .catch((err) => {
          expect(err).to.be.an('error')
            .with.property('message', 'Oops!');
        });
    });

    // ...
  });
});
Другие вопросы по тегам