2016-04-28 58 views
2

我對NodeJS.I非常新,我需要一些幫助來測試我使用Express構建的簡單API。在Nodejs中使用模擬模塊測試高速路由

我在我的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); 
}); 

這將呼叫路由共享的方法queryDB它正在利用其RESTful接口的泰坦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

我能夠測試我的API與下游this SO answer嘲笑下游系統。

但我不確定這是否是最好的/唯一的方法。

0

我發現的唯一方法是改變app.use('/ users',userRoute);userRoute(APP)

// 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嘲笑你的依賴encies:

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

非常感謝埃文Shortiss:

http://evanshortiss.com/development/javascript/2016/04/15/express-testing-using-ioc.html