【问题标题】:Closing server after mocha test, but data is still there摩卡测试后关闭服务器,但数据仍然存在
【发布时间】:2015-05-31 18:35:54
【问题描述】:

我正在尝试通过 REST API 测试一些数据。数据以数组形式存储在项目中。

我希望每次运行测试套件时都“恢复”数据,以便我知道数组中的数据量。

但是当我测试帖子时。插入的元素在下一个测试套件中,即使我在每次测试之前启动和停止服务器。

app.js 需要用户数组,所以通过停止和启动服务器,我认为在每次测试之前我都会干净,但事实并非如此

谢谢。

 global.test = true;

    // Test server setup
    var app = require('../app');
    var testPort = 9999;
    var testServer;

    // Dependencies
    var should = require('should');
    var request = require('request');

    var baseUrl = 'http://localhost:9999/api';

    describe('RESTApi : GET Methods', function () {
        //Start the Server before the TESTS
        beforeEach(function (done) {

            testServer = app.listen(testPort, function () {
                console.log("Server is listening on: " + testPort);
                done();
            })
                .on('error', function (err) {
                    console.log(err);
                });
        });

        afterEach(function () {  //Stop server after the test
            testServer.close(function () {
                console.log("closing server");
            });
        });

     TEST here           

    });

    describe('RESTApi : POST Methods', function () {
        //Start the Server before the TESTS
        before(function (done) {

            testServer = app.listen(testPort, function () {
                console.log("Server is listening on: " + testPort);
                done();
            })
                .on('error', function (err) {
                    console.log(err);
                });
        });

        after(function () {  //Stop server after the test
            testServer.close(function () {
                console.log("closing server");
            });
        });

       TEST here

    });

----- App.js ----- 我知道 REST api 应该在它自己的文件夹中。 :)

var path = require('path');
        var bodyParser = require('body-parser');

        //For testing to delete the cached user array
        delete require.cache[require.resolve('./users')];

        var users = require('./users');
        var express = require('express');

        function findUser(users, email) {
            var result = users.filter(function(u) {
                return u.email === email;
            });
            if(result.length >= 1) {
                return result[0];
            }
            return undefined;
        }

        var app = express();

        app.use(bodyParser.json());
        app.use(bodyParser.urlencoded({ extended: false }));


        app.get("/api/users", function(req, res) {
            res.send(users);
        });

        app.get("/api/users/:email", function(req, res) {
            var user = findUser(users, req.params.email);
            if(!user) {
                return res.status(404).send({error: "user not found"});
            }
            res.send(user);
        });

        app.post("/api/users", function(req, res) {
            var user = req.body;
            if(findUser(users, user.email)) {
                return res.status(400).send({error: "user exist"});
            }
            users.push(user);
            res.send(user);
        });

        app.put("/api/users/:email", function(req, res) {
            var user = req.body;
            if(!findUser(users, req.params.email)) {
                return res.status(404).send({error: "user not found"});
            }
            if(!user) {
                return res.status(404).send({error: "no user provided"});
            }
            for(var i = 0; i < users.length; i += 1) {
                if(users[i].email === user.email) {
                    users[i].password = user.password;
                    break;
                }
            }
            res.send(user);
        });

        app.delete("/api/users/:email", function(req, res) {
            var user = findUser(users, req.params.email);
            if(!user) {
                return res.status(404).send({error: "user not found"});
            }
            for(var i = 0; i < users.length; i++) {
                if(users[i].email === req.params.email) {
                    users.splice(i, 1);
                    break;
                }
            }
            res.send(user);
        });

        app.all('*', function(req, res) {
            res.status(500).send(req.url + " not a valid");
        });

        if(global.activeTest === undefined){
            app.listen(3000, function() {
                console.log("Rest API started, listen on port 3000");
            });
        }

        module.exports = app;

【问题讨论】:

  • 你能显示app.js吗?
  • 当然,它已添加。我尝试删除兑现的数据并且有效。但是如果有更好的方法让我知道:)
  • 感谢您添加app.js 代码。删除缓存的必需用户真的有效吗?这对我来说没有意义,但如果你真的尝试/测试过它,我无法与你争论。我将提出一个不同的解决方案,包括将初始化user var 的代码重构为一个函数并将其公开,以便您可以在每次测试之前“重新初始化”它。我会尽快发布我提出的解决方案。

标签: javascript node.js express mocha.js


【解决方案1】:

我的解决方案(正如我在上面的评论中提到的)是将初始化 users var 的代码重构为一个单独的函数,可以在每次测试之前调用。

var path = require('path');
var bodyParser = require('body-parser');
var express = require('express');
var clone = require('clone'); // <-- add `clone` as a dependency

var users;
function initUsers() {
  users = clone(require('./users'));
}

// ... the rest if your code, initializing express/adding route handlers

app.listen(3000, function() {
  console.log("Rest API started, listen on port 3000");
});

module.exports = exports = app;
exports.initUsers = initUsers;

将此作为我在users.js 中的示例数据:

module.exports = [
  { email: 'email0', password: 'password0' },
  { email: 'email1', password: 'password1' },
  { email: 'email2', password: 'password2' },
  { email: 'email3', password: 'password3' },
  { email: 'email4', password: 'password4' },
  { email: 'email5', password: 'password5' },
  { email: 'email6', password: 'password6' },
  { email: 'email7', password: 'password7' },
  { email: 'email8', password: 'password8' },
  { email: 'email9', password: 'password9' }
];

我在每次测试前调用initUsers()能够成功测试,如下:

var app = require('../app');
var initUsers = require('../app').initUsers;

var should = require('should');
var request = require('request');

var baseUrl = 'http://localhost:3000/api';

describe('RESTApi', function() {

  describe('GET Methods', function () {

    beforeEach(function() {
      initUsers();
    });

    it('should get all users initially', function(done) {
      request(baseUrl + '/users', function(err, res) {
        var data = JSON.parse(res.body);
        data.length.should.equal(10);
        done();
      });
    });

    it('should remove user', function(done) {
      request.del(baseUrl + '/users/email1', function(err, res) {
        var data = JSON.parse(res.body);
        data.email.should.equal('email1');
        data.password.should.equal('password1');

        request(baseUrl + '/users', function(err, res) {
          var data = JSON.parse(res.body);
          data.length.should.equal(9);
          done();
        });

      });
    });

    it('should get all users again', function(done) {
      request(baseUrl + '/users', function(err, res) {
        var data = JSON.parse(res.body);
        data.length.should.equal(10);
        done();
      });
    });

  });

});

如你所见,我写了三个测试。

  1. 获取所有用户(验证初始计数为 10)
  2. 删除用户(验证计数现在为 9)
  3. 获取所有用户(验证计数现在再次为 10)

这些绝不是详尽的测试,但它们会验证 users 在每次测试之前都已正确初始化。

【讨论】:

  • 正是我想要的,非常感谢!在您的 app.js 版本中,您使用 module.exports = exports = app;那和 module.exports = app; 有什么区别?
  • 欢迎您。 module.exports/exports 问题超出了本问题的范围。如果您想要技术差异,请查看NodeJS doc。此外,该问题已在 stackoverflow 中提出/回答,请参阅here
【解决方案2】:

看起来app.listen() 是异步的,因此无论服务器是否停止,您的测试都会继续运行。我会将您的测试放在callback 参数中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2018-03-08
    • 2019-04-24
    相关资源
    最近更新 更多