Search code examples
node.jsmocha.jskoa

NodeJs / Koa - Error payload not defined inside unit tests


I need help figure out something: I use https://github.com/mjhea0/node-koa-api as a base to develop my API.

In the routes/movies.js file you can see that he uses :

router.get(`${BASE_URL}/:id`, async (ctx) => {
  try {
    const movie = await queries.getSingleMovie(ctx.params.id);
    if (movie.length) {
      ctx.body = {
        status: 'success',
        data: movie
      };
    } else {
      ctx.status = 404;
      ctx.body = {
        status: 'error',
        message: 'That movie does not exist.'
      };
    }
  } catch (err) {
    console.log(err)
  }
})

To make the GET /movies/id route and inside unit tests :

describe('GET /api/v1/movies/:id', () => {
  it('should throw an error if the movie does not exist', (done) => {
    chai.request(server)
    .get('/api/v1/movies/9999999')
    .end((err, res) => {
      // there should an error
      should.exist(err);
      // there should be a 404 status code
      res.status.should.equal(404);
      // the response should be JSON
      res.type.should.equal('application/json');
      // the JSON response body should have a
      // key-value pair of {"status": "error"}
      res.body.status.should.eql('error');
      // the JSON response body should have a
      // key-value pair of {"message": "That movie does not exist."}
      res.body.message.should.eql('That movie does not exist.');
      done();
    });
  });
});

To test for the wrong id.

I have the exact same code in my router but for my own entity 'guilds' :

router.get('/api/v1/guilds/:id', async (ctx) => {
  try {
    const guild = await queries.getOneGuild(ctx.params.id);
    if (guild.length) {
      ctx.body = {
        status: 'success',
        data: guild,
      };
    } else {
      ctx.status = 404;
      ctx.body = {
        status: 'error',
        message: 'That guild does not exist.',
      };
    }
  } catch (err) {
    console.log(err);
  }
});

And inside my tests/routes.guilds.test.js is the same as the referenced github repo :

describe('GET /api/v1/guilds/:id', () => {
  it('should throw an error if the guild does not exist', (done) => {
    chai.request(server)
     .get('/api/v1/guilds/9999999')
     .end((err, res) => {
       console.log(err);
       should.exist(err);
       // there should be a 404 status code
       res.status.should.equal(404);
       // the response should be JSON
       res.type.should.equal('application/json');
       // the JSON response body should have a
       // key-value pair of {"status": "error"}
       res.body.status.should.eql('error');
       // the JSON response body should have a
       // key-value pair of {"message": "That guild does not exist."}
       res.body.message.should.eql('That guild does not exist.');
       done();
     });
  });
});

My problem is that line :

// there should an error
should.exist(err);

In the referenced GitHub: err is set to a value, while in my code err is undefined ...

I don't understand why the referenced GitHub code as the err set to a big array of data in

.end((err, res) => {})

And mine isn't even defined. Especially since I do the same stuff...

It's my first Koa / Node.js API so that I might have just missed something.

Thanks in advance for any input!

Edit: Forgot to say that.

ctx.status = 404;
ctx.body = {
  status: 'error',
  message: 'Guild not found.'
};

actually works and I can see their values in Mocha's Unit-Tests :

.end((err, res) => {
  console.log(res.status); // Prints 404
  console.log(res.body.message); // Prints 'Guild not found'
});

Its seems Koa / Koa-router inside the referenced Github repo automatically sees it as an error and sets something while in my code it doesn't...

Edit 2: Because of the first answer is given, I tested to remove the try catch block inside the referenced GitHub source code, and their unit test still works so it has nothing to do with the try catch block.

router.get(`${BASE_URL}/:id`, async (ctx) => {
  const movie = await queries.getSingleMovie(ctx.params.id);
  if (movie.length) {
     ctx.body = {
       status: 'success',
       data: movie
     };
   } else {
     ctx.status = 404;
     ctx.body = {
       status: 'error',
       message: 'That movie does not exist.'
     };
   }
});

as the same behavior regarding the unit-tests: Err is still set inside routes.movies.test.js


Solution

  • I found the problem, this github repo uses chai-http@3.0.0 and i was using chai-http@4.2.0

    in chai-http@4.0.0 they removed the err argument if the request is successful.

    Issue was solved by just keeping chai-http@4.2.0 and removing should.exists(err)

    Thanks to : https://github.com/tgriesser/knex/issues/1855