用 mocha 测试 Node.js api

Testing Node.js api with mocha

我正忙于为我编写的现有 nodejs api 构建功能测试。我正在使用 mocha 和 expect.js.

一个失败的测试是当我想对 url 参数的存在进行否定测试时。我想要的是在缺少参数的情况下向服务的消费者发送一条消息。

目前我的阳性测试有效:

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) { ... });
});

但是,下面的方法不起作用,我得到的只是超时:

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();
        }
    });
});

以上两个测试都在测试这个端点:

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 ...
});

但是,如前所述,第一次测试成功,第二次测试超时。

更新 1: 此外,我得到以下输出:

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

更新 2: 所以添加如下代码解决了问题,但并没有真正解决问题:

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

显然我不希望有一段相当多余的代码。我很困惑为什么我不能输入 'api/v1/user/:userid' 端点并只测试那里是否存在 :userid?就好像nodejs要求存在:userid,否则端点不存在。这是正确的吗?

我错过了什么?

根据 mocha documentation 必须始终调用 done 回调,即使出现错误也是如此。事实上它接受一个错误。 所以我认为你必须重写你的代码:

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) return done(error);
        if (response.statusCode != 400) return done(new Error("Not 400"));

        expect(body).to.be.equal('UserId expected');
        done();
    });
});

所以我做了更多调查,并就此问题提出了另一个问题

最后的问题是我没有完全理解express框架。基本上,我在问题的更新 2 中提到的是我需要遵循的路线,并指定一条不需要参数的路线,但是 return 我在这种情况下期望的错误消息。

我在使用这种方法时遇到的问题是,在某些情况下,您可能想在 ur 中使用多个参数。然而,这将意味着为满足参数未定义的每种情况而进行的排列会有点令人生畏。 (2 个参数表示 4 个组合,3 个表示 9 个等等)这将是一场维护噩梦!

从现在开始,我的方法将是遵循一种方法,即我想传递给服务器的任何信息都将通过每个请求正文中的 JSON 发送。这将允许我只走一条路线。