在请求后使用 supertest 和 co 验证数据库内容
Using supertest and co to validate database content after request
我想编写一个测试来更新博客 post(或其他):
* 在数据库中插入博客post
* 获取博客 post 在 MongoDb 中的 ID
* POST 我端点的更新版本
* 请求完成后:检查更新已经完成的数据库
这是这个,使用 koa:
var db = require('../lib/db.js');
describe('a test suite', function(){
it('updates an existing text', function (done) {
co(function * () {
var insertedPost = yield db.postCollection.insert({ title : "Title", content : "My awesome content"});
var id = insertedPost._id;
var url = "/post/" + id;
var updatedPost = { content : 'Awesomer content' };
request
.post(url)
.send(updatedTextData)
.expect(302)
.expect('location', url)
.end(function () {
co(function *() {
var p = yield db.postCollection.findById(id);
p.content.should.equal(updatedPost.content);
console.log("CHECKED DB");
})(done());
});
});
});
});
我意识到其中有很多活动部件,但我已经分别测试了所有交互。这是我包含的 db 文件(我知道它工作正常,因为我在生产中使用它):
var monk = require('monk');
var wrap = require('co-monk');
function getCollection(mongoUrl, collectionName) {
var db = monk(mongoUrl);
return wrap(db.get(collectionName));
};
module.exports.postCollection = getCollection([SECRET MONGO CONNECTION], 'posts');
生产代码按预期工作。
这个测试通过了,但在我看来,.end() 子句中的协同函数从来没有 运行... 但是完成了 done() 调用。至少没有 "CHECKED DB" 被打印出来。
我试过使用 "done()" 和 "done" 不使用。有时这行得通,有时行不通。
我试图将数据库的检查移到请求之外......但是它只是挂起,因为 supertest 希望我们在完成时调用 done()。
所有这些让我感到困惑和害怕 (:)) - 我在这里做错了什么。
发生这种情况是因为
var p = yield db.postCollection.findById(id);
是最后一行将在您的生成器函数中执行。
你可以通过添加一个console.log('before first yield').
来测试我是否正确
yield 是生成器函数中 return 的替代品,但如果您第二次调用该函数,它会运行到下一个 yield。
A generator-function is executed from yield to yield
(最好用简短的方式解释它 - 我认为)。
您的解决方案:
在数据库查找之前简单地擦除产量:
var p = db.postCollection.findById(id);
意识到这个问题非常冗长和具体,我担心我永远不会得到正确的答案。由于提出了严重的问题。
但是给出的答案和评论让我又看了一遍,我找到了。我写了一个 long blog post about it 但我会在这里给出它的结尾作为总结。如果它没有意义,那么在博客 post.
中还有更多相同的 :)
这里是 TL;DR:
我想在发出请求后检查数据库的状态。这可以使用 supertest.
的 .end() 函数来完成
因为我用了co-monk I wanted to be able to do that using yield and generators. This means that I need to wrap my generator function with co.
co,从 4.0.0 版开始,returns 一个承诺。这非常适合 mocha 的用户,因为它允许我们使用 .then() 函数并将 done 变量传递给 .then(fn success, fn failure(err)).[= 的成功和失败函数。 15=]
完整的测试如下所示。 运行 这个 returns 由于断言失败导致的错误,如我所愿:
var co = require("co");
var should = require("should");
var helpers = require('./testHelpers.js');
var users = helpers.users;
var request = helpers.request;
describe('POST to /user', function(){
var test_user = {};
beforeEach(function (done) {
test_user = helpers.test_user;
helpers.removeAll(done);
});
afterEach(function (done) {
helpers.removeAll(done);
});
it('creates a new user for complete posted data', function(done){
// Post
request
.post('/user')
.send(test_user)
.expect('location', /^\/user\/[0-9a-fA-F]{24}$/) // Mongo Object Id /user/234234523562512512
.expect(201)
.end(function () {
co(function *() {
var userFromDb = yield users.findOne({ name : test_user.name });
userFromDb.name.should.equal("This is not the name you are looking for");
}).then(done, done);
});
});
});
我想编写一个测试来更新博客 post(或其他): * 在数据库中插入博客post * 获取博客 post 在 MongoDb 中的 ID * POST 我端点的更新版本 * 请求完成后:检查更新已经完成的数据库
这是这个,使用 koa:
var db = require('../lib/db.js');
describe('a test suite', function(){
it('updates an existing text', function (done) {
co(function * () {
var insertedPost = yield db.postCollection.insert({ title : "Title", content : "My awesome content"});
var id = insertedPost._id;
var url = "/post/" + id;
var updatedPost = { content : 'Awesomer content' };
request
.post(url)
.send(updatedTextData)
.expect(302)
.expect('location', url)
.end(function () {
co(function *() {
var p = yield db.postCollection.findById(id);
p.content.should.equal(updatedPost.content);
console.log("CHECKED DB");
})(done());
});
});
});
});
我意识到其中有很多活动部件,但我已经分别测试了所有交互。这是我包含的 db 文件(我知道它工作正常,因为我在生产中使用它):
var monk = require('monk');
var wrap = require('co-monk');
function getCollection(mongoUrl, collectionName) {
var db = monk(mongoUrl);
return wrap(db.get(collectionName));
};
module.exports.postCollection = getCollection([SECRET MONGO CONNECTION], 'posts');
生产代码按预期工作。 这个测试通过了,但在我看来,.end() 子句中的协同函数从来没有 运行... 但是完成了 done() 调用。至少没有 "CHECKED DB" 被打印出来。
我试过使用 "done()" 和 "done" 不使用。有时这行得通,有时行不通。 我试图将数据库的检查移到请求之外......但是它只是挂起,因为 supertest 希望我们在完成时调用 done()。
所有这些让我感到困惑和害怕 (:)) - 我在这里做错了什么。
发生这种情况是因为
var p = yield db.postCollection.findById(id);
是最后一行将在您的生成器函数中执行。
你可以通过添加一个console.log('before first yield').
来测试我是否正确yield 是生成器函数中 return 的替代品,但如果您第二次调用该函数,它会运行到下一个 yield。
A generator-function is executed from yield to yield
(最好用简短的方式解释它 - 我认为)。
您的解决方案: 在数据库查找之前简单地擦除产量:
var p = db.postCollection.findById(id);
意识到这个问题非常冗长和具体,我担心我永远不会得到正确的答案。由于提出了严重的问题。
但是给出的答案和评论让我又看了一遍,我找到了。我写了一个 long blog post about it 但我会在这里给出它的结尾作为总结。如果它没有意义,那么在博客 post.
中还有更多相同的 :)这里是 TL;DR:
我想在发出请求后检查数据库的状态。这可以使用 supertest.
的 .end() 函数来完成因为我用了co-monk I wanted to be able to do that using yield and generators. This means that I need to wrap my generator function with co.
co,从 4.0.0 版开始,returns 一个承诺。这非常适合 mocha 的用户,因为它允许我们使用 .then() 函数并将 done 变量传递给 .then(fn success, fn failure(err)).[= 的成功和失败函数。 15=]
完整的测试如下所示。 运行 这个 returns 由于断言失败导致的错误,如我所愿:
var co = require("co");
var should = require("should");
var helpers = require('./testHelpers.js');
var users = helpers.users;
var request = helpers.request;
describe('POST to /user', function(){
var test_user = {};
beforeEach(function (done) {
test_user = helpers.test_user;
helpers.removeAll(done);
});
afterEach(function (done) {
helpers.removeAll(done);
});
it('creates a new user for complete posted data', function(done){
// Post
request
.post('/user')
.send(test_user)
.expect('location', /^\/user\/[0-9a-fA-F]{24}$/) // Mongo Object Id /user/234234523562512512
.expect(201)
.end(function () {
co(function *() {
var userFromDb = yield users.findOne({ name : test_user.name });
userFromDb.name.should.equal("This is not the name you are looking for");
}).then(done, done);
});
});
});