我是Node.js,Mongoose的新手,并在此环境中进行测试。我在单独的文件中声明了以下架构。
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});
}
});
}
我已经通过实验获得了这一点,现在我想测试它,但我遇到了一个问题。如何在不设置MongoDB连接的情况下进行测试,我知道我可以设置所有这些内容,但这是一个集成测试。我想编写单元测试来测试像:
date
字段我很想知道如何重构现有代码以使其更具单元可测试性。我已经尝试过创建第二个被调用的函数,接受response
和Item
模式对象作为参数,但感觉不对。有谁有更好的建议?
答案 0 :(得分:8)
Mongoose model
(您的Issue
)返回Query
对象的新实例。新的query
实例可以通过exec
访问prototype
方法。 (猫鼬3.8~)
如果要返回错误,可以写:
sinon.stub(mongoose.Query.prototype, "exec").yields({ name: "MongoError" }, null);
答案 1 :(得分:6)
在我的节点代码中使用mocha和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);
});
答案 2 :(得分:1)
我不确定如何测试Content-Type,我自己也没有测试过这段代码,但如果它不起作用我很乐意帮忙。这似乎对我有意义。基本上我们只是创建了一个回调函数,因此我们可以将response.send
移出实际的自定义逻辑,然后我们可以通过该回调进行测试。如果它不起作用或有意义,请告诉我。您可以使用其他人发布的链接来防止必须连接到数据库。
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');
});
}
答案 3 :(得分:0)
一个好的起点是: