我想测试我的服务器。 测试提供了简单的场景:
我尝试使用mocha进行测试,并使用supertest进行请求。
测试示例:
function request(url, query, cb) {
var req = supertest(app.listen())
.get(url)
.query(query)
.end(function(err, res){
if (err) {throw (err);}
cb(res);
});
}
it('Check something after response', function *(done) {
request(this.url, this.query, function(res) {/* some after response check here */});
});
现在我需要将我的回调式代码重组为生成器式代码。
我需要这样的东西:
it('Check something in response', function *(done) {
var res = yield request(this.url, this.query);
/* some after response check here */
});
不幸的是,我无法理解我需要在request()
P.S。我没有注意到具有适当风格的其他supertest
类似解决方案。我只是想通过这个简单的例子来理解如何包装回调。
答案 0 :(得分:1)
基本上,要将回调代码重写为生成器样式,您需要:
yield someAsyncFunc(cb)
iter.next(value)
next
一次示例:
console.info=function(x){document.write('<pre>'+JSON.stringify(x,0,3)+'</pre>')}
//--
// some async function with a callback
function asyncFunc(done) {
setTimeout(function() {
done(Math.random())
}, 500);
}
// generator
function *gen() {
var val;
val = yield asyncFunc(advanceIter);
console.info(val)
val = yield asyncFunc(advanceIter);
console.info(val)
}
// create an iterator
iter = gen()
// define a callback for the async function
function advanceIter(value) {
iter.next(value);
}
// get the whole machinery started
iter.next()
当然,在现实世界中,你将把你的发电机包裹在一个负责所有内务管理的功能中。您的生成器将接收advance
参数,它应该盲目地进一步作为对它使用的异步函数的回调。
console.info=function(x){document.write('<pre>'+JSON.stringify(x,0,3)+'</pre>')}
//--
function asyncFunc(done) {
setTimeout(function() {
done(Math.random())
}, 500);
}
function run(gen) {
var iter = gen(function(value) {
iter.next(value)
});
iter.next()
}
run(function *(advance) {
var val;
val = yield asyncFunc(advance);
console.info(val)
val = yield asyncFunc(advance);
console.info(val)
});
请注意,异步函数本身不需要进行任何更改(在您的情况下为request
)。
测试框架的一个例子:
// some async function we're going to test
function asyncFunc(param, cb) {
setTimeout(function () {
cb(param + '-ok');
}, 500);
}
// classic async test
describe('async demo', function () {
it('works', function (done) {
asyncFunc('foobar', function (result) {
expect(result).toBe('foobar-ok');
done();
})
});
});
// generator test
// note that asyncFunc itself remains unchanged
function run(gen) {
var iter = gen(function (value) {
iter.next(value)
});
iter.next()
}
describe('yield demo', function () {
it('works', function (done) {
run(function *(advance) {
var result = yield asyncFunc('barbaz', advance);
expect(result).toBe('barbaz-ok');
done();
})
});
});
// generator test 2
// adding more automation
function runGen(gen) {
return function (done) {
var iter = gen(function (value) {
var r = iter.next(value);
if (r.done)
done();
});
iter.next();
}
}
describe('yield demo 2', function () {
it('works', runGen(function *(advance) {
var result = yield asyncFunc('quux', advance);
expect(result).toBe('quux-ok');
}));
});
答案 1 :(得分:1)
怎么样:
function* request (url, query) {
supertest(app.listen())
.get(url)
.query(query)
.end((err, res) => {
if (err) {
throw err;
}
yield res;
});
}
it('Check something after response', done => {
const res = request(this.url, this.query).next();
expect(res).to.be.defined
});