2016-11-29 7 views
2

Как часть переноса старого приложения из ExpressJs в Koa JS (v1). Я написал часть промежуточного программного обеспечения для обработки любых ошибок, которые происходят. Это выглядит примерно так:Как проверить пользовательское связующее ПО Koa для обработки ошибок?

module.errors = function * (next) { 
    try { 
    yield next; 
    } catch (err) { 
    switch(err && err.message) { 
     case: 'Bad Request': 
     this.status = 400; 
     this.body = {message: 'Bad Request'}; 
     brea; 
     default: 
     this.status = 500; 
     this.body = {message: 'An error has occurred'}; 
    } 

    this.app.emit('error', err, this); 
    } 
} 

Он получает включенный в моем приложении, как это:

const app = require('koa')(); 
const router = require('koa-router'); 
const { errors } = require('./middleware/errors'); 

app.use(errors) 
    .use(router.routes()); 

app.get('/some-request', function *(next){ 
    // request that could error 
}); 

app.listen(); 

Это все работает отлично, но я хотел бы проверить промежуточный с моими модульными тестами, и, возможно, потому что я до сих пор довольно новичок в функциях Koa и Generator, я изо всех сил пытаюсь понять, как это сделать.

Я знаю, что если я импортирую промежуточное программное обеспечение обработки ошибок, мне нужно передать ему функцию, которая будет вызывать ошибку, но как выполнить переданную функцию? Нужно ли закрывать какое-то описание? Как я могу утверждать/ожидать значения, установленные для кода состояния и тому подобного?

const { expect } = require('chai'); 
const { errors } = require('../middleware/errors'); 

describe('errors middleware',() => { 

    it('returns a 500 on a generic error',() => { 
     let thrower = function(){ throw new Error() } 
     let errorHandler = errors(thrower()); 

     // mass of confusion 

     expect(errorHandler.next()).to.throw(Error); 
    }); 
}); 

ответ

0

Коа являются генераторами промежуточных программным (возврат/выход несколько раз) и не ведут себя как функции, поэтому он чувствует себя странно писать тесты для них. Лично мне достаточно иметь сквозные тестовые примеры.

Однако в вашем случае может работать следующее.

const { expect } = require('chai'); 
const { errors } = require('../middleware/errors'); 

describe('errors middleware',() => { 

    it('returns a 500 on a generic error',() => { 

     let ctx = { body: {}, status: 404 }; 

     let errorMidIterator = errors().call(ctx, 'NEXT_MID'); 

     // test that it correctly yields to next middleware 
     expect(errorMidIterator.next().value).should.equal('NEXT_MID'); 

     // simualte an error and test if it correctly sets the body 
     expect(errorMidIterator.throw(new Error()).done).to.equal(true); 
     expect(ctx.status).should.equal(500); 
    }); 
}); 

Как примечание стороны, я считаю, что лучше экспортировать межплатформенные заводы из файлов, а не функции генератора равнины промежуточных программного обеспечения. Первый дает вам больше контроля (т. Е. Вы можете ввести некоторые из зависимостей, в этом случае функцию thrower(), через аргументы функции Factory). Мои файлы промежуточного программного обеспечения выглядят так.

module.exports = function MyMiddleware(options) { 
    return function *MyMiddleware(next) { 
     // options.config.foo 
     // options.httpclient.get(..) 
    }; 
} 

Наконец КоА обертывание функции генератора с соавторами, которая изменяет семантику, так как юнит-тесты не то, что полезно (субъективные)

0

вы можете использовать эту библиотеку https://www.npmjs.com/package/co, которая используется при koa.js 1.x к оберните ваши функции генератора и издевайтесь над объектом контекста.

const co = require('co'); 
const Emitter = require('events'); 
const { expect } = require('chai'); 
const { errors } = require('../middleware/errors'); 

const wrapped = co.wrap(errors); 
const mockApp = new Emitter(); 

describe('errors middleware',() => { 

    it('returns a 500 on a generic error', (done) => { 
    const ERROR_MSG = 'middleware error'; 
    const ctx = {app: mockApp}; 
    const next = function*() { 
     throw new Error(ERROR_MSG); 
    } 
    wrapped.call(ctx, next) 
     .then(() => { 
     try { 
      expect(ctx.status).to.equal(500); 
      expect(ctx.body.message).to.equal(ERROR_MSG); 
      done(); 
     } catch (err) { 
      done(err); 
     } 
     }) 
     .catch(err => done(err)) 

    }); 
});