【问题标题】:Test Express Route in Nodejs with mocked Module使用模拟模块在 Nodejs 中测试 Express Route
【发布时间】:2016-04-28 22:13:53
【问题描述】:

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

此路由调用共享方法 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 等等

感谢任何帮助或建议。谢谢。

【问题讨论】:

    标签: node.js unit-testing express mocking


    【解决方案1】:

    我可以使用在 this SO answer 之后模拟的下游系统来测试我的 API。

    但是我不确定这是否是最好/唯一的方法。

    【讨论】:

      【解决方案2】:

      我发现的唯一方法是将 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 来模拟你的依赖:

      // 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

      【讨论】:

        猜你喜欢
        • 2021-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-27
        • 2015-12-16
        • 1970-01-01
        • 2018-12-05
        • 2022-06-12
        相关资源
        最近更新 更多