unit testing与mongoose

我是Node.js,Mongoose和在这个环境中testing的新手。 我有以下模式在一个单独的文件中声明。

Issue = mongoose.model("Issue", { identifier: String, date: String, url: String, name: String, thumbnailURL: String }); 

然后我有这个方法,它只是返回MongoDB集合中的所有Issue实例。

 function issues(request, response) { response.setHeader('Content-Type', 'text/json'); Issue.find().sort('date').exec(function(error, items) { if (error) { response.send(403, {"status": "error", "error:": exception}); } else { response.send(200, {"issues": items}); } }); } 

我已经通过实验得到了很多,现在我想testing它,但是我遇到了一个问题。 我怎么去testing它,而没有build立一个MongoDB连接等。我知道我可以设置所有的东西,但这是一个集成testing。 我想编写unit testing来testing如下的东西:

  • 函数是否正确设置内容types
  • 函数按date字段进行sorting
  • 发生错误时函数是否返回403?
  • … 等等

我很好奇,看看我可以重构我现有的代码,使其更容易testing。 我已经尝试过创build第二个被调用的函数,接受responseItem模式对象作为参数,但是感觉不对。 任何人有更好的build议?

在我的节点代码中使用摩卡与chaijs和sinonjs类似这种方法适用于我:

 var should = require('chai').should(), sinon = require('sinon'), mongoose = require('mongoose'); it('#issues() handles mongoosejs errors with 403 response code and a JSON error message', function (done) { // mock request var request = {}; // mock response var response = {}; response.setHeader = function(header) {}; response.send = function (responseCode, jsonObject) { responseCode.should.equal(403); jsonObject.stats.should.equal('error'); // add a test for "error:": exception done(); } var mockFind = { sort: function(sortOrder) { return this; }, exec: function (callback) { callback('Error'); } } // stub the mongoose find() and return mock find mongoose.Model.find = sinon.stub().returns(mockFind); // run function issues(request, response); }); 

Mongoose model (您的Issue )返回Query对象的新实例。 新的query实例可以通过prototype访问exec方法。 (mongoose3.8〜)

如果你想返回一个错误,你可以写:

 sinon.stub(mongoose.Query.prototype, "exec").yields({ name: "MongoError" }, null); 

我不知道如何testingContent-Type,我自己也没有testing过这个代码,但是如果它不起作用,我很乐意帮忙。 这似乎对我有意义。 基本上我们只是创build了一个callback,所以我们可以将response.send移出实际的自定义逻辑,然后我们可以通过callback进行testing。 让我知道,如果它不工作或没有意义。 您可以使用其他人发布的链接来防止连接到数据库。

 Issue = mongoose.model("Issue", { identifier: String, date: String, url: String, name: String, thumbnailURL: String }); function issues(callback, request, response) { Issue.find().sort('number').exec(function(error, items) { if (error) { callback(403, {"status": "error", "error:": exception}); } else { callback(200, {"issues": items}); } }); } //Note: probably don't need to make a whole new `sender` function - depends on your taste function sender(statusCode, obj) { response.setHeader('Content-Type', 'text/json'); response.send(statusCode, obj); } //Then, when you want to implement issues issues(sender, request, response); //The tests - will depend on your style and test framework, but you get the idea function test() { //The 200 response issues(function(code, obj) { assert(code === 200); assert(obj.issues === ??); //some testable value, or just do a truthy test //Here, you can also compare the obj.issues item to the proper date-sorted value }); //The error response issues(function(code, obj) { assert(code === 403); assert(code.status === 'error'); }); } 

一个好的开始将是:

  1. 调查存根和嘲笑的概念,并testing双打。
  2. 查看一下Node.JS的Mocking框架的Sinon.js