如何unit testingexpress路由器路由

我是Node和Express的新手,我试图unit testing我的路线/控制器。 我已经从我的控制器中分离出我的路线。 我如何去testing我的路线?

configuration/ express.js

var app = express(); // middleware, etc var router = require('../app/router')(app); 

应用程序/路由器/ index.js

  module.exports = function(app) { app.use('/api/books', require('./routes/books')); }; 

应用程序/路由器/路由/ books.js

  var controller = require('../../api/controllers/books'); var express = require('express'); var router = express.Router(); router.get('/', controller.index); module.exports = router; 

应用程序/ API /控制器/ books.js

 // this is just an example controller exports.index = function(req, res) { return res.status(200).json('ok'); }; 

应用程序/testing/ API /路由/ books.test.js

  var chai = require('chai'); var should = chai.should(); var sinon = require('sinon'); describe('BookRoute', function() { }); 

       

网上收集的解决方案 "如何unit testingexpress路由器路由"

码:

configuration/ express.js

 var app = express(); // middleware, etc var router = require('../app/router')(app); module.exports = app; 

应用程序/testing/ API /路由/ books.test.js

 var chai = require('chai'); var should = chai.should(); var sinon = require('sinon'); var request = require('supertest'); var app = require('config/express'); describe('BookRoute', function() { request(app) .get('/api/books') .expect('Content-Type', /json/) .expect('Content-Length', '4') .expect(200, "ok") .end(function(err, res){ if (err) throw err; }); }); 

注意事项:

如果您的服务器在一组testing开始时需要初始状态(因为您正在执行调用服务器状态的调用),则需要编写一个函数,该函数将返回一个新configuration的应用程序,并且每组试验。 有一个NPM库: https : //github.com/bahmutov/really-need ,这将允许你需要一个新的实例化版本的服务器。

当我testing自己的服务器端点时,我发现这个博客非常有洞察力。

他在博客中写道:

  • 如何使用terminaltesting库supertest 。

  • 如何在每个端点testing之前和之后以编程方式启动并拆除具有所需路由的快速服务器。 (他也解释了为什么你会这样做)。

  • 如何避免一个常见的问题,需要caching你的unit testing所需的模块,导致意想不到的后果。

希望这可以帮助。 祝你好运,如果你还有任何问题,请告诉我。

这很有趣,因为你已经把你的控制器从路由器中分离出来了。 另一个StackOverflow文章中提到的评论是一个很好的方式来testing你的控制器,我想。 unit testing要记住的是你正在testing什么。 你应该不需要编写testing来testing快速库,因为大概它有自己的unit testing。 所以你只需要testing你对图书馆的电话。 所以对于书本路线,你只需要testing这一行代码:

 router.get('/', controller.index); 

我环顾四周,看是不是有一个明显的方法从快递库里find路线清单,但是我没有看到。 你可能只是看看库本身,并检查其内部,看看你是否正确设置路线。 另一个select是嘲笑它,只是检查你是否正确地调用它。

这将变得相当复杂,因为你需要模拟Javascript的一些基本部分来testing这一行代码。 以下是我如何做到的:

 describe('BookRoute', function() { it("should route / to books controller index", function() { var controller = require('../../../api/controllers/books'); var orig_this = this; var orig_load = require('module')._load; var router = jasmine.createSpyObj('Router', ['get']); var express = jasmine.createSpyObj('express', ['Router']); express.Router.and.returnValues(router); spyOn(require('module'), '_load').and.callFake(function() { if (arguments[0] == 'express') { return express; } else { return orig_load.apply(orig_this, arguments); } }); require("../../../router/routes/books"); expect(router.get).toHaveBeenCalledWith('/', controller.index); }); }); 

这里发生了什么是我用Jasmine的spyOn函数侦听module.js中的_load函数,它是处理所有require调用的函数。 这是当我们需要书籍路由器,它调用require('express')时,我们可以返回我们使用jasmine.createSpyObj创build的SpyObj。 一旦我们用我们的间谍对象明确地取代,那么我们可以让它返回我们的路由器SpyObj,这将让我们窥探router.get。 然后我们可以检查以确保它被调用'/'和controller.index。

如果你想用这个,可能会把它变成某种效用。

我通常通过使用更多面向对象的方法来避免很多这样的事情,或者我可以在任何地方传递一些对象来模拟testing,也可以使用像Angular这样的dependency injection。