簡體   English   中英

使用 sinon 對 express.js 路由進行單元測試

[英]Unit testing express.js route with sinon

我正在學習 express 和 sinon(很難:))。 我想對以下代碼進行單元測試:

//  ./routers/root.js

var express = require('express');
var router = express.Router();

router
  .route('/')
  .get(function(req, res) {
    res.writeHead(200, {'Content-Type': 'application/json'});
    res.write(JSON.stringify({Application: "NodeTours", Version: "2.0.0", Host: host, Port: port}));
    res.end();
  });

module.exports = router;

我一直在嘗試不同的事情但沒有成功。 我回到基本的例子。 我意識到這似乎是一個完整的新手問題,但我一無所知。 這是最新的嘗試:

//   ./test/test.js

var sinon = require('sinon')
var expect = require('chai').expect

describe('Routers', function() {

  context('/', function() {
    var rootRouter = require('../routers/root')
    var res = {Application: "NodeTours", Version: "2.0.0", Host: 'host', Port: 'port'};
    it('should call / router', function() {
      rootRouter.route('/').get(null, res);
      // TODO: expect...
    })
  })
})

它失敗了:

  Routers
    /
      1) should call / router


  0 passing (4ms)
  1 failing

  1) Routers
       /
         should call / router:
     Error: Route.get() requires a callback function but got a [object Null]
      at Route.<computed> [as get] (node_modules/express/lib/router/route.js:202:15)
      at Context.<anonymous> (test/test.js:10:29)
      at processImmediate (internal/timers.js:456:21)

我已經嘗試了多個教程但沒有成功。 我將不勝感激任何有關如何對我的代碼進行單元測試的指針。 或者如何調整我的代碼以便單元測試更容易/可能。

我的主要應用程序 server.js 文件用於上下文和參考(已刪除與此問題無關的代碼)

//   ./server.js
// npm pacakages
var express = require('express');
var bodyParser = require('body-parser');

// app imports
var { rootRouter } = require('./routers');
// other cut out

//globals
app = express();
app.use(bodyParser.json());
app.use('/', rootRouter);
// other cut out

// Set up Mongo DB connection
// code to st up db connection

// Start server (only if connection to DB established)
var server = MongoClient(url, { useUnifiedTopology: true, poolSize: 10 }).connect().then(client => {
  const dbo = client.db(dbName);

  // some init code cut out

  // make connection available
  app.locals.dbo = dbo;

  // start server
  app = app.listen(process.env.PORT || 7777, function () {
    host = require('os').hostname();
    port = "7777";
    logger.verbose("Startup: NodeTours listening at http://%s:%s", host, port)
  });
}).catch(error => {
  logger.error("Startup: Couldn't connect to the DB. The app will exit")
  logger.error("  Error: " + error)
  process.exit();
  }
);

在您的測試用例中,您嘗試直接調用 GET 處理程序:

it('should call / router', function() {
  rootRouter.route('/').get(null, res);
  // TODO: expect...
})

但是appRouter.route('/').get()是一種旨在安裝請求處理程序的方法,而不是調用它。 這就是為什么你得到的錯誤說:

錯誤:Route.get() 需要回調 function 但得到 [object Null]

即,您將null傳遞給您認為的請求參數,但 Express 期望的將是方法(回調)處理程序。

通常我要做的是將我的處理程序定義為非匿名函數:

function rootHandler(req, res) {
    res.writeHead(200, {'Content-Type': 'application/json'});
    res.write(JSON.stringify({Application: "NodeTours", Version: "2.0.0", Host: host, Port: port}));
    res.end();
}

router
  .route('/')
  .get(rootHandler);

...然后單元測試可以簡單地直接調用 function,而不是通過 Express 調用 go(因為通常我們有興趣測試我們自己的代碼,而不是框架):

it('should do something with root handler', function() {
  rootHandler(null, res);
  // TODO: expect...
})

如果您真的想測試路由邏輯,那么按照評論中的建議使用supertest是一個不錯的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM