2

在简单的单元测试中使用 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 数据库并仍然像上面显示的那样运行集成测试?

4

1 回答 1

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

应用程序.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!

    });
});

我希望它适用于你或任何人。

于 2017-08-23T17:07:31.683 回答