Тестирование приложения Node.js, использующего Kue
Я хотел бы протестировать приложение, которое использует Kue, так что очередь заданий пуста перед каждым тестом и очищается после каждого теста. Очередь должна быть полностью функциональной, и мне нужно иметь возможность проверять состояние заданий, которые уже находятся в очереди.
Я пробовал mock-kue, и он работал хорошо, пока мне не пришлось получать задания из очереди и анализировать их. Я не мог заставить его вернуться на работу по идентификатору работы.
Ситуации, которые мне нужно проверить:
- Что-то происходит, и в очереди должна быть работа заданного типа,
- Что-то происходит и производит работу. Что-то еще происходит, и это задание удаляется и заменяется другим заданием (перепланирование или существующее задание).
Швы прямолинейны, но мне трудно обдумать проблему. Все указатели приветствуются.
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!');
});
});
// ...
});
});