Как проверить приложение express с помощью mocha?
Я только что добавил shouldjs и mocha в мое экспресс-приложение для тестирования, но мне интересно, как проверить мое приложение. Я хотел бы сделать это так:
app = require '../app'
routes = require '../src/routes'
describe 'routes', ->
describe '#show_create_user_screen', ->
it 'should be a function', ->
routes.show_create_user_screen.should.be.a.function
it 'should return something cool', ->
routes.show_create_user_screen().should.be.an.object
конечно, последний тест в этом тестовом наборе просто говорит med, что функция Res.render (вызываемая в show_create_user_screen) не определена, вероятно, потому что сервер не работает, и конфигурация не была выполнена. Поэтому мне интересно, как другие люди настраивают свои тесты?
5 ответов:
хорошо, во-первых, хотя тестирование кода маршрутизации-это то, что вы можете или не хотите делать, в общем, попробуйте отделить свою интересную бизнес-логику в чистом коде javascript (классы или функции), которые отделены от express или любой другой структуры, которую вы используете, и используйте тесты vanilla mocha для проверки этого. Как только вы достигли этого, если вы хотите действительно протестировать маршруты, которые вы настраиваете в mocha, вам нужно пройти mock
req, res
параметры в функции промежуточного программного обеспечения для имитации интерфейс между express / connect и вашим промежуточным программным обеспечением.для простого случая, вы можете создать макет С
render
функция, которая выглядит примерно так.describe 'routes', -> describe '#show_create_user_screen', -> it 'should be a function', -> routes.show_create_user_screen.should.be.a.function it 'should return something cool', -> mockReq = null mockRes = render: (viewName) -> viewName.should.exist viewName.should.match /createuser/ routes.show_create_user_screen(mockReq, mockRes).should.be.an.object
также просто функции промежуточного программного обеспечения FYI не должны возвращать какое-либо конкретное значение, это то, что они делают с
req, res, next
параметры, на которых вы должны сосредоточиться в тестировании.вот некоторые JavaScript, как вы просили в комментариях.
describe('routes', function() { describe('#show_create_user_screen', function() { it('should be a function', function() { routes.show_create_user_screen.should.be.a["function"]; }); it('should return something cool', function() { var mockReq = null; var mockRes = { render: function(viewName) { viewName.should.exist; viewName.should.match(/createuser/); } }; routes.show_create_user_screen(mockReq, mockRes); }); }); });
нашел альтернативу подключиться.Яш тестов
они с помощью Супертест для тестирования приложения connect без привязки сервера к какому-либо Порту и без использования макетов.
вот выдержка из статического набора тестов промежуточного программного обеспечения connect (используя mocha в качестве тестового бегуна и супертеста для утверждений)
var connect = require('connect'); var app = connect(); app.use(connect.static(staticDirPath)); describe('connect.static()', function(){ it('should serve static files', function(done){ app.request() .get('/todo.txt') .expect('contents', done); }) });
это работает и для экспресс-приложений
вы можете попробовать SuperTest, а затем запустить и завершить работу сервера:
var request = require('supertest') , app = require('./anExpressServer').app , assert = require("assert"); describe('POST /', function(){ it('should fail bad img_uri', function(done){ request(app) .post('/') .send({ 'img_uri' : 'foobar' }) .expect(500) .end(function(err, res){ done(); }) }) });
мокко приходит раньше, после каждого, после, и еще после каждой для проверки БДД. В этом случае вы должны использовать before в своем описании вызова.
describe 'routes' -> before (done) -> app.listen(3000) app.on('connection', done)
Я обнаружил, что проще всего настроить класс TestServer для использования в качестве помощника, а также помощник http-клиента, и просто сделать реальные запросы к реальному http-серверу. Однако могут быть случаи, когда вы хотите высмеять и заглушить этот материал.
// Test file var http = require('the/below/code'); describe('my_controller', function() { var server; before(function() { var router = require('path/to/some/router'); server = http.server.create(router); server.start(); }); after(function() { server.stop(); }); describe("GET /foo", function() { it('returns something', function(done) { http.client.get('/foo', function(err, res) { // assertions done(); }); }); }); }); // Test helper file var express = require('express'); var http = require('http'); // These could be args passed into TestServer, or settings from somewhere. var TEST_HOST = 'localhost'; var TEST_PORT = 9876; function TestServer(args) { var self = this; var express = require('express'); self.router = args.router; self.server = express.createServer(); self.server.use(express.bodyParser()); self.server.use(self.router); } TestServer.prototype.start = function() { var self = this; if (self.server) { self.server.listen(TEST_PORT, TEST_HOST); } else { throw new Error('Server not found'); } }; TestServer.prototype.stop = function() { var self = this; self.server.close(); }; // you would likely want this in another file, and include similar // functions for post, put, delete, etc. function http_get(host, port, url, cb) { var options = { host: host, port: port, path: url, method: 'GET' }; var ret = false; var req = http.request(options, function(res) { var buffer = ''; res.on('data', function(data) { buffer += data; }); res.on('end',function(){ cb(null,buffer); }); }); req.end(); req.on('error', function(e) { if (!ret) { cb(e, null); } }); } var client = { get: function(url, cb) { http_get(TEST_HOST, TEST_PORT, url, cb); } }; var http = { server: { create: function(router) { return new TestServer({router: router}); } }, client: client }; module.exports = http;