0

I am writing integration test for a nodejs/sails js application, where I have an Async controller method/route that throws error when input parameters are not provided.

I am using supertest to write integration test, everything works fine from my perspective, but when the test run error is written onto the console.

describe("a controller method", () => {
  it("should throw error message", () => {
    server('127.0.0.1')
    .get('url to getData')
    .set('Cookie', 'cookie token')
    .end((err, res) => {
      if(err) return done(err);
      //console.log(res);
      expect(res.status).to.equal(500);
      expect(res.body).to.have.property('error', 'Provide a jobName');
      done();
    });
  });
});

enter image description here

This following piece of code works fine cause I wrap this within an anonymous function and expect that function to throw. But I am not sure how to assert against those error.

it("throws", () => {
      expect( function () {
        server('127.0.0.1')
      .get('some url')
      .set('Cookie', 'cookie token')
      }).to.throw;
    });

The controller code looks like following. This is the method that is being called when URL end is requested.

getData : async (req, res) => {

    let jobName = req.params.jobName || '',
        buildId = req.params.buildId || '';

    if(!jobName.trim() ){
      return res.negotiate({error:'Provide a jobName'});
    }

    if(isNaN(buildId)) {
      return res.negotiate({error:'Invalid build id supplied.'});
    }

    try {
      let rawResult = await getData(jobName, buildId);
      let promotions = formatData(rawResult);

      let result = {
        total : promotions.length || 0,
        items : promotions
      };
      return res.json(result);
    } catch(error) {
      sails.log.error(`Request Parameter: Job name = ${req.param('jobName')} & build id = ${req.param('buildId')}`);
      sails.log.error(error);
      return res.negotiate({error: sails.config.errorMessage});
    }
  }

Why is the error being written to console ? What am I doing wrong here? Any help/pointer is highly appreciated!!

Saroj
  • 1,551
  • 2
  • 14
  • 30

2 Answers2

0

How are you sending that error from express? In general express follows the way of passing errors rather than throwing it, for any errors in the program you can pass the error object to 'next' function. http://expressjs.com/en/guide/error-handling.html

e.g

 app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})
Lucas Lago
  • 146
  • 6
  • please see my update to question. FYI this is basically a Sails Js application that negotiates with error using sails.negotiate(). – Saroj Feb 26 '18 at 14:05
0

async returns a promise and although you have placed a try catch block, my guess is the error is not in the block. It is most likely due to the promise rejection not getting handled.

The below should be of help to you as applying to the sails context.

since async functions return a promise, you need to .catch() any promise rejections and pass them along to next(). Express error handlers are only triggered by errors passed to next(), not exceptions that you throw. Source

And for promise()=> reject

user2347763
  • 469
  • 2
  • 10
  • How is it possible ? I checked that method is being called, if you see I get the error object added to console. Please see the screen shot attached to the question. – Saroj Feb 27 '18 at 15:12
  • What are you trying here? The screenshot is obviously different from what the describe message says. – user2347763 Feb 27 '18 at 16:04
  • 1
    Sorry , the getData method is actually the code from another method I pasted it here in a hurry, I am changing it now. But the idea is the request hit that method and the error should be thrown but shouldn't shown on the console. The code just below the screen-shot is passes because the getData() throws error, but when we use Supertest with .end((err, res) => {}) it acutally execute that method and error is thrown. – Saroj Feb 28 '18 at 07:06