如何在快速应用程序集成测试中使用mockgoose(或任何其他数据库模拟)

时间:2017-07-14 17:26:44

标签: mongodb express testing integration-testing mockgoose

在简单的单元测试中使用mockgoose非常简单。但是我对如何在验收或集成测试中使用mockgoose或其他模拟解决方案感到有点模糊。

给出一个简单的express / MongoDB应用程序,如下所示:

/*app.js*/

const express = require('express')
const app = express()
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var greetingSchema = mongoose.Schema({
    greeting: String
});

var Greeting = mongoose.model('Greeting', greetingSchema);

app.get('/', function (req, res) {
  Greeting.find({greeting: 'Hello World!'}, function (err, greeting){
    res.send(greeting);
  });  
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})

和这样的简单集成测试:

/*test.js*/

const app = require('app.js');  
const request = require('supertest');

it('sends "Hello World!" on the response body', (done) => {  
  request(app)
      .get('/')
      .expect(200, 'Hello World!', done);
  });
});

通过在请求中使用实际应用程序,我们将连接到应用程序的数据库('mongodb:// localhost / test')。那么如何使用mockgoose或任何其他解决方案来模拟MongoDB数据库并仍然运行如上所示的集成测试?

1 个答案:

答案 0 :(得分:8)

我和你有同样的问题。在我的例子中,我解决了使用chai + chai-http并在不同的文件中打破数据库连接和应用程序:

<强> db.js

const mongoose = require('mongoose');
const config = require('../../config');
mongoose.Promise = global.Promise;
mongoose.set('debug', process.env.DEBUG != undefined);

function open(){
    return new Promise((resolve, reject) => {
        if(process.env.DEBUG != undefined) {
            let Mockgoose = require('mockgoose').Mockgoose;
            let mockgoose = new Mockgoose(mongoose);
            mockgoose.helper.setDbVersion("** your mongodb version **");
            mockgoose.prepareStorage().then(function() {
                mongoose.connect(config.db_test, (err, res) => {
                  if (err) return reject(err);
                  resolve();
                });
            }).catch(reject);
        }else{
            mongoose.connect(config.db, (err, res) => {
              if (err) return reject(err);
              resolve();
            });
        }
    });
}

function close(){
    return mongoose.disconnect();
}

module.exports = { close, open };

<强> app.js

const express = require('express');

const bodyParser = require('body-parser');
const api = require('./routes');

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

app.use('/api', api);

module.exports = app;

test.js (用于测试):

const chai = require('chai');
const chaiHttp = require('chai-http');
const expect = chai.expect;
const conn = require('./../utils/db'); // <-- db.js
const app = require('../../app'); // <-- app.js

chai.use(chaiHttp);

describe('# Test', function(){

    before(function(done) {
        conn.open().then(() => done()).catch(done);
    });

    after(function(done){
        conn.close().then(() => done()).catch(done);
    });

    it(`test something`, function(done){

        chai.request(app) // <-- pass the app here
            .get('/path/to/test')
            .then((res) => {
                // expects

                done();
              })
              .catch((err) => {
                  done(err);
              });
    });
});

index.js (用于开发或制作):

const conn = require('./utils/db'); // <-- db.js
const app = require('./app'); // <-- app.js
const config = require('./config'); 

conn.open().then(() => {
    app.listen(config.port, () => {

        // OK!

    });
});

我希望它适合你或任何人。