最近,我试图在Mongoose作为MongoDB包装器的Node JS中进行良好的测试驱动开发。
我的问题是我做得对吗?我是否正在测试正确的东西,我是否应该进行更多覆盖空值的测试等等。您认为我可以提高哪些内容?随意批评你喜欢的。
测试
var assert = require("assert"),
mongoose = require("mongoose"),
sugar = require("sugar"),
Factory = require("factory-lady"),
Timekeeper = require("timekeeper"),
Link = require("./../app/models/link");
mongoose.connect("mongodb://localhost/link_test");
Factory.define("link", Link, {
createdAt: new Date("2012-04-04"),
title: "Example",
updatedAt: new Date("2012-04-05"),
url: "http://www.example.com"
});
describe("Link", function() {
describe("validation for", function() {
["url", "title"].forEach(function(property) {
it("must have a " + property, function(done) {
Factory.build("link", function(link) {
link[property] = null;
link.validate(function(err) {
assert.notEqual(err, null);
assert.notEqual(err.errors[property], null);
done();
});
});
});
});
it("should default the title to url if missing", function(done) {
Factory.build("link", function(link) {
link.title = undefined;
link.validate(function(err) {
assert.equal(link.title, link.url);
done();
});
});
});
describe("url", function() {
["http://example.com", "http://www.example.com",
"http://nodejs.org/api/assert.html#assert_assert_deepequal_actual_expected_message"].forEach(function(url) {
it(url + " should be valid url", function(done) {
Factory.build("link", { url: url }, function(link) {
link.validate(function(err) {
assert.equal(err, null);
done();
});
});
});
});
["Invalid url", "example.com"].forEach(function(url) {
it(url + " should be invalid url", function(done) {
Factory.build("link", { url: url }, function(link) {
link.validate(function(err) {
assert.notEqual(err, null);
assert.notEqual(err.errors.url, null);
done();
});
});
});
});
});
describe("missing createdAt or updatedAt", function() {
beforeEach(function() {
Timekeeper.freeze(new Date());
});
afterEach(function() {
Timekeeper.reset();
});
["createdAt", "updatedAt"].forEach(function(property) {
it("should default the " + property + " to now if missing", function(done) {
Factory.build("link", function(link) {
link[property] = undefined;
link.validate(function(err) {
assert.deepEqual(link[property], new Date());
done();
});
});
});
});
["createdAt", "updatedAt"].forEach(function(property) {
it("should leave the " + property + " unchanged if it's given", function(done) {
Factory.build("link", function(link) {
var date = new Date("2012-01-01");
link[property] = date;
link.validate(function(err) {
assert.deepEqual(link[property], date);
done();
});
});
});
});
it("should default the updatedAt to now if missing when performing an update", function(done) {
Factory("link", function(link) {
link.validate(function(err) {
assert.equal(link.updatedAt, new Date());
done();
});
});
});
it("should leave the updatedAt unchanged if it's given when performing an update", function(done) {
Factory("link", function(link) {
var date = new Date("2012-01-01");
link.updatedAt = date;
link.validate(function(err) {
assert.deepEqual(link.updatedAt, date);
done();
});
});
});
});
});
});
型号:
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
var linkSchema = new Schema({
createdAt: { type: Date, required: true },
title: { type: String, required: true },
updatedAt: { type: Date, required: true },
url: { type: String, required: true, validate: [validUrl, "invalid url"] }
});
function validUrl(url) {
if ((url instanceof String || typeof url == 'string') && url.length) {
return url.match(/^\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))$/i);
}
}
linkSchema.pre("validate", function (next) {
if (typeof this.title === "undefined" && typeof this.url !== "undefined") {
this.title = this.url;
}
if (typeof this.createdAt === "undefined") {
this.createdAt = new Date();
}
if (typeof this.updatedAt === "undefined" || !this.isModified("updatedAt")) {
this.updatedAt = new Date();
}
next();
});
module.exports = mongoose.model("Link", linkSchema);
答案 0 :(得分:1)
总而言之,您的测试似乎涵盖了代码。 也许您可以添加更多URL以更好地测试 validUrl 函数。
通常,要完成的测试数量取决于您的需求。是否需要更多测试取决于许多因素,例如:您对代码的信心,可能触及代码并“破坏”代码的人数,整个系统的大小和复杂性,代码的用户(他们是你的团队的一部分还是局外人?),数据的来源(在它到达你的代码之前是否经过验证?)和你的偏执程度。没有一个万能的答案。