[英]Unit tests: Testing inner Promise
I've been searching the web for a while and I've yet to find the answer to this. 我已经在网上搜索了一段时间,但尚未找到答案。
Let's say we're testing the following: 假设我们正在测试以下内容:
function p() {
return Promise.resolve(1);
}
class Sample {
constructor() {
this.stuff = 2;
}
sample () {
p().then((data) => {
this.stuff = data;
});
//more stuff
}
}
module.exports = {Sample};
How could we check that, eventually this.stuff
is populated without returning said promise? 我们如何检查该结果,最终填充
this.stuff
而不返回上述承诺?
This is what I've been able to do until now: 到目前为止,这是我能够做的:
let expect = require('chai').expect;
let sinon = require('sinon');
let Sample = require('./source.js').Sample;
describe('stuff', function () {
it('test2', function() {
let sample = new Sample();
return Promise.resolve(sample.sample())
.then(() => {
expect(sample.stuff).to.be.eql(2);
});
});
});
In which, each then
gets the next tick (if we had multiple then
s in our sample we'd also need multiple then
s in our test). 其中,每个
then
得到一个信用(如果我们有多个then
是我们的样本中,我们想也需要多个then
S IN我们的测试)。
(And before you say process.nextTick
, I want this to run in the browser with karma-mocha) (并且在您说
process.nextTick
之前,我希望它可以通过karma-mocha在浏览器中运行)
Thanks in advance! 提前致谢!
This could be easily tested if the code was restructured, to support testability. 如果代码经过重组以支持可测试性,则可以很容易地对其进行测试。
One way to do this would be to take an optional p
interface for the object instantiation. 一种方法是为对象实例化使用可选的
p
接口。 The value could default to your defined p
but would allow for a test to create a fake object and verify that your Sample
operates on it correctly. 该值可以默认为您定义的
p
但允许进行测试以创建伪造的对象并验证您的Sample
是否在其上正确运行。
function p() {
return Promise.resolve(1);
}
class Sample {
constructor(pFn) {
this.stuff = 2;
this.p = pFn || p;
}
sample () {
this.p().then((data) => {
this.stuff = data;
});
//more stuff
}
}
This would allow you to provide a promise-like object, for your unit test, that executes synchronously. 这将允许您为单元测试提供一个类似promise的对象,该对象可以同步执行。
One way would be to periodically check for the set value. 一种方法是定期检查设置值。
it('test2', function(done) {
let sample = new Sample();
let assert = function() {
if(sample.stuff === 2) {
done();
} else {
setTimeout(assert, 0);
}
};
sample.sample();
assert();
});
It's not the prettiest, and won't give the best error message on a failure, but it would work. 它不是最漂亮的,并且不会在失败时给出最佳的错误消息,但是它可以工作。 If
sample.stuff
isn't set to 2
within a couple seconds (I think 3 seconds is the default) then the test will fail because done()
was not called in time. 如果没有在两秒钟内将
sample.stuff
设置为2
(我认为默认值为3秒),则测试将失败,因为未及时调用done()
。
Another possible option is to have the test replace stuff
with a setter. 另一个可能的选择是让测试用设置器替换
stuff
。 Then you can expect()
on set. 然后您可以在set上
expect()
。
it('test2', function(done) {
let sample = new Sample();
Object.defineProperty(sample, 'stuff', { set: function (value) {
expect(value).to.be.eql(2);
done();
}});
sample.sample();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.