我是NodeJS的新手。我需要一些帮助来测试我用Express构建的简单API。
我的API中有以下路线:
router.get('/execute', function(req, res, next) {
console.log("Execute Request Query: %s", util.inspect(req.query, false, null));
// Validate Reqest. gremlin is Mandatory field
if (req == null || req.query.gremlin == null) {
res.status(400).send(getErrorResponse("Invalid Request", "Request is missing mandatory field: gremlin"));
return;
}
queryDB(req.query.gremlin, res);
});
此Route调用一个共享方法queryDB,它使用Restful接口对Titan DB进行API调用。我正在使用node_module Restler进行此API调用。
function queryDB(query, res) {
console.log("Constructed Gremlin Query: %s. Querying Titan with URL: %s", util.inspect(query, false, null), titanBaseUrl);
rest.postJson(titanBaseUrl,
{ gremlin: query },
{ headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }
).on('complete', function(data, response) {
if (response != null && response.rawEncoded != null && response.statusCode / 100 == 2) {
console.log("Call successful. Response.rawEncoded: %s", util.inspect(response.rawEncoded, false, null));
res.send(getResult(response));
} else {
console.error("Call failed. Response: %s", util.inspect(response, false, null));
res.status(500).send(getErrorResponse("Bad Gremlin Response", response));
}
});
}
现在,我想测试我的API的“执行”端点。我可以通过以下方式完成此任务:
var www = require("../bin/www");
var superagent = require('superagent');
var expect = require('expect.js');
var proxyquire = require('proxyquire');
describe('server', function() {
before(function() {
www.boot();
});
describe('Execute', function() {
it('should respond to GET', function(done) {
superagent
.get('http://localhost:' + www.port + "/gremlin/execute?gremlin=99-1")
.end(function(err, res) {
expect(res.status).to.equal(200);
expect(res.body.data[0]).to.equal(98);
done()
})
})
});
after(function() {
www.shutdown();
});
});
但是我正在调用我需要模拟的数据库。我在网上看到一些例子可以帮助你模拟我可以用来模拟“Restler”的节点模块。但是,由于我通过调用端点来测试API,因此我不确定如何为此模拟模块。
我看了下面的例子: https://stackoverflow.com/a/33773233/2596762 https://www.terlici.com/2015/09/21/node-express-controller-testing.html 等
感谢任何帮助或建议。感谢。
答案 0 :(得分:0)
我可以使用this SO answer下面模拟的下游系统来测试我的API。
但我不确定这是否是最佳/唯一的方式。
答案 1 :(得分:0)
我找到的唯一方法是使用 userRoute(app)更改 app.use('/ users',userRoute); :
// file: main.js
var express = require('express');
var app = express();
var userRoute = require('./user-route');
// Have user route mount itself to the express application, we could pass
// other parameters too, such as middleware, or the mount path
userRoute(app);
为每条路线创建特殊模块:
// file: user-route.js
var express = require('express');
var users = require('./users');
module.exports = function (app) {
var route = express.Router();
// Mount route as "/users"
app.use('/users', route);
// Add a route that allows us to get a user by their username
route.get('/:username', function (req, res) {
var user = users.getByUsername(req.params.username);
if (!user) {
res.status(404).json({
status: 'not ok',
data: null
});
} else {
res.json({
status: 'ok',
data: user
});
}
});
};
然后您可以使用proxyquire来模拟您的依赖项:
// We'll use this to override require calls in routes
var proxyquire = require('proxyquire');
// This will create stubbed functions for our overrides
var sinon = require('sinon');
// Supertest allows us to make requests against an express object
var supertest = require('supertest');
// Natural language-like assertions
var expect = require('chai').expect;
var express = require('express');
describe('GET /ping', function () {
var app, getUserStub, request, route;
beforeEach(function () {
// A stub we can use to control conditionals
getUserStub = sinon.stub();
// Create an express application object
app = express();
// Get our router module, with a stubbed out users dependency
// we stub this out so we can control the results returned by
// the users module to ensure we execute all paths in our code
route = proxyquire('./user-route.js', {
'./users': {
getByUsername: getUserStub
}
});
// Bind a route to our application
route(app);
// Get a supertest instance so we can make requests
request = supertest(app);
});
it('should respond with a 404 and a null', function (done) {
getUserStub.returns(null);
request
.get('/users/nodejs')
.expect('Content-Type', /json/)
.expect(404, function (err, res) {
expect(res.body).to.deep.equal({
status: 'not ok',
data: null
});
done();
});
});
it('should respond with 200 and a user object', function (done) {
var userData = {
username: 'nodejs'
};
getUserStub.returns(userData);
request
.get('/users/nodejs')
.expect('Content-Type', /json/)
.expect(200, function (err, res) {
expect(res.body).to.deep.equal({
status: 'ok',
data: userData
});
done();
});
});
});
非常感谢Evan Shortiss:
http://evanshortiss.com/development/javascript/2016/04/15/express-testing-using-ioc.html