node.jsapimocha.jsexpect.js

Testing Node.js api with mocha


I am busy building functional tests for an existing nodejs api I wrote. I am using mocha and expect.js.

One test that is failing is when I want to do a negative test for the existence of a url parameter. What I want is to send a message back to the the consumer of the service if the param is missing.

Currently the positive test I have works:

var request = require('request');

it('get a specific user from the api', function (done) {
    request.get('http://localhost:8080/api/v1/user/123', function (error, response, body) { ... });
});

However, the following does not work and all I get is a timeout:

it('should return a 400 message if UserId is not supplied stating that "UserId expected"', function(done) {
    request.get('http://localhost:8080/api/v1/user/', function (error, response, body) { 
        if (!error && response.statusCode == 400) {
            expect(body).to.be.equal('UserId expected');
            done();
        }
    });
});

Both the above tests are testing this endpoint:

app.get('/api/v1/user/:userid', function (req, res) {
    if(!req.params.userid) {
        return res.status(400).json('UserId expected');
    }

    ... get the user and return it with status 200 ...
});

However, as stated before, the first test is successful while the second test times out.

Update 1: Additionally, I am getting the following output:

GET /api/v1/user/123 200 2.905 ms - 274
GET /api/v1/user/ - - ms - -

Update 2: So adding the following code solves the problem, but doesn't really solve the problem:

app.get('/api/v1/user', function (req, res) {
    return res.status(400).json('UserId expected');
});

Obviously I don't want a rather redundant piece of code sitting around. I am baffled as to why I cannot enter the 'api/v1/user/:userid' endpoint and just test for the existence of :userid in there? It's as if nodejs is requiring the existence of :userid, otherwise the endpoint does not exist. Is this correct?

What am I missing?


Solution

  • So I did some more investigation and asked another question regarding this issue here.

    In the end the issue was that I didn't fully understand the express framework. Basically what I alluded to in Update 2 of my question is the route I will need to follow and specify a route where no param is expected, but return the error message I am expecting in that case.

    The problem I have with this approach is that in some instances one might want to use more than one parameter in the ur. However, this will mean the permutations to cater for each scenario where a parameter is undefined gets a bit daunting. (2 params will mean 4 combinations, 3 will mean 9 etc.) This will be a maintenance nightmare!

    My approach from now on will be to rather follow an approach where any info I want to pass to the server will be sent via JSON in the body from of each request. This will allow me to keep to one single route.