node.js 如何使用 mocha 测试我的 Express 应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8831984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:00:18  来源:igfitidea点击:

How do i test my express app with mocha?

node.jsexpressmocha

提问by Robin Heggelund Hansen

I've just added shouldjs and mocha to my express app for testing, but I'm wondering how to test my application. I would like to do it like this:

我刚刚将 shouldjs 和 mocha 添加到我的 express 应用程序中进行测试,但我想知道如何测试我的应用程序。我想这样做:

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

Of course, the last test in that test-suite just tells med that the res.render function (called within show_create_user_screen) is undefined, probably becouse the server is not running and the config has not been done. So I wonder how other people set up their tests?

当然,该测试套件中的最后一个测试只是告诉 med res.render 函数(在 show_create_user_screen 中调用)未定义,可能是因为服务器未运行且配置尚未完成。所以我想知道其他人是如何设置测试的?

采纳答案by Peter Lyons

OK, first although testing your routing code is something you may or may not want to do, in general, try to separate your interesting business logic in pure javascript code (classes or functions) that are decoupled from express or whatever framework you are using and use vanilla mocha tests to test that. Once you've achieved that if you want to really test the routes you configure in mocha, you need to pass mock req, resparameters into your middleware functions to mimic the interface between express/connect and your middleware.

好的,首先,尽管测试您的路由代码是您可能想要或可能不想做的事情,但一般来说,尝试将您感兴趣的业务逻辑分离到与 express 或您正在使用的任何框架分离的纯 JavaScript 代码(类或函数)中,并且使用香草摩卡测试来测试。一旦你实现了这一点,如果你想真正测试你在 mocha 中配置的路由,你需要将模拟req, res参数传递到你的中间件函数中,以模拟 express/connect 和中间件之间的接口。

For a simple case, you could create a mock resobject with a renderfunction that looks something like this.

对于一个简单的情况,您可以创建一个res带有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

Also just FYI middleware functions don't need to return any particular value, it's what they do with the req, res, nextparameters that you should focus on in testing.

另外仅供参考,中间件函数不需要返回任何特定值,这是它们对req, res, next您在测试中应该关注的参数所做的事情。

Here is some JavaScript as you requested in the comments.

这是您在评论中要求的一些 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);
      });
    });
  });

回答by alexandru.topliceanu

found an alternative in connect.js tests suites

connect.js 测试套件中找到了替代方案

They are using supertestto test a connect app without binding the server to any port and without using mock-ups.

他们正在使用supertest来测试连接应用程序,而无需将服务器绑定到任何端口,也无需使用模型。

Here is an excerpt from connect's static middleware test suite (using mocha as the test runner and supertest for assertions)

以下是 connect 的静态中间件测试套件的摘录(使用 mocha 作为测试运行程序和 supertest 进行断言)

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

This works for express apps as well

这也适用于 express 应用程序

回答by LeeGee

You could try SuperTest, and then server start-up and shutdown are taken care of:

您可以尝试使用 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();
        })
  })
});

回答by fent

mocha comes with before, beforeEach, after, and afterEach for bdd testing. In this case you should use before in your describe call.

mocha 带有 before、beforeEach、after 和 afterEach 用于 bdd 测试。在这种情况下,您应该在 describe 调用中使用 before。

describe 'routes' ->
  before (done) ->
    app.listen(3000)
    app.on('connection', done)

回答by Bryan Donovan

I've found it's easiest to set up a TestServer class to be used as a helper, as well as a helper http client, and just make real requests to a real http server. There may be cases where you want to mock and stub this stuff instead though.

我发现将 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;