hemerajs / hemera

🔬 Writing reliable & fault-tolerant microservices in Node.js https://hemerajs.github.io/hemera/
MIT License
806 stars 70 forks source link

AddStub.run ignores Validaiton #103

Closed KeKs0r closed 7 years ago

KeKs0r commented 7 years ago

Hi,

I am currently playing around with hemera and was rewriting a small app from seneca. I am using Joi Validation and wanted to test it with the approach that is documented for unit tests. This is the Plugin I am trying to test:

function EventStorePlugin (options, next) {
  this.use(require('hemera-joi'))
  this.setOption('payloadValidator', 'hemera-joi')

  this.add(
    {
      topic: 'events',
      cmd: 'add',
      events: Joi.array().required()
    },
    (msg, reply) => {
      msg.events.forEach(store.add)
      reply(null, {success:true})
    }
  )
next()
}

But it seems that Running unit tests against this, is not checking for Validation: Test

const Hemera = require('nats-hemera')
const Nats = require('hemera-testsuite/natsStub')
const AddStub = require('hemera-testsuite/addStub')
const nats = new Nats()
const h = new Hemera(nats, { logLevel: 'fatal' })
h.use(require('../handlers'))

test('Requires a valid Event', done => {
  expect.assertions(5)
  h.ready(() => {
    AddStub.run(
      h,
      {
        topic: 'events',
        cmd: 'add'
      },
      { events: 1 },
      (err, res) => {
        expect(err).toBeTruthy()
        done()
      }
    )
  })
})

Is there a way of getting validation to work with the AddStub?

StarpTech commented 7 years ago

Hi @KeKs0r that's correct we only stub the handler function not the middleware. I think you are looking for integration test but you can extract the joi schema from the schema. You can get it with addStub.schema.joi$

StarpTech commented 7 years ago
const pattern = {...}
//test implementation
const addStub = AddStub.run(h, pattern)

//check joi schema
addStub.schema.joi$.validate(pattern).error === null

If you want to do an integration test look at https://github.com/hemerajs/hemera/blob/master/test/hemera/index.spec.js

Important: hemera-testsuite was created to write tests if you have already a running application and want to stub external calls to services. The recommend way is to outsource your business code in a seperate container and call them directly from hemera. Now you can easily test your code independent from hemera.

hemera.add(pattern, function * (req) {
   return yield MyService.getUsers()
})

test

it('Should return all users') {
  return MyService.getUsers().then((r) => {
    Code.expect(r.data.length).to.be.equals(true)
  })
}
KeKs0r commented 7 years ago

I want to check that my Validation works in combination with missing parameters. And it seems that the handler is still called and then throws errors (due to missing arguments). I think I need to test validation manually. Which is not optimal, since the pattern defines not only a Joi Schema, but also the routing pattern. So it seems I can't test the combination.

StarpTech commented 7 years ago

@KeKs0r I dont see the problem. You can validate the whole pattern seperatly.

Joi.validate(pattern, addStub.schema, {
  allowUnknown: true
}, (err, value) => {

})
KeKs0r commented 7 years ago

Yep I am now directly Validating with Joi against the Schema:

  test('requires customer', (done) => {
    expect.assertions(2)
    const pattern = {
      topic: 'order',
      cmd: 'create'
    }
    const payload = { product: 5 }
    const addStub = AddStub.run(h, pattern, payload)
    Joi.validate(payload, addStub.schema, (err) => {
      expect(err).toBeTruthy()
      expect(err.message).toMatch(/customer/)
      done()
    })
  })