我遇到了一个非常奇怪的问题:我正在尝试进行单元测试以在我的应用程序上实现 100% 的测试覆盖率。 当然,我为我的 Controller 编写了一些测试,但似乎无法使用 ember-cli 测试 Ember (2.4.0) 中的任何异步内容。
我在 Controller 中有一个函数可以执行此操作:
readObject() { this.store.findRecord('myModel',1).then(function(obj) { this.set('property1',obj.get('property2'); }.bind(this)); }
我正在编写一个应该涵盖此功能的测试。
test('action readObject', function (assert) { const cont = this.subject(); cont.readObject(); assert.equal(cont.get('property1'), 'someValue); });
显然,这个断言不起作用,因为 readObject() 是异步调用,但这不是问题的根源。问题是,然后 this.store.findRecord 中的回调正在执行 - 我的 Controller 已经被破坏!所以我得到了“在被破坏的对象上调用集”错误。
换句话说 - 即使我将我的函数包装在一个 promise 中并重新格式化这两个函数,如下所示:
readObject() {
return new Promise(function(resolve) {
this.store.findRecord('myModel',1).then(function(obj) {
this.set('property1',obj.get('property2');
resolve();
}.bind(this));
}.bind(this));
}
和
test('action readObject', function (assert) {
const cont = this.subject();
cont.readObject().then(function() {
assert.equal(cont.get('property1'), 'someValue);
});
});
它不起作用,因为执行 readObject() 后我的 Controller 立即被销毁,而不等待任何回调。 因此,它可以是任何异步调用,而不是 store.findRecord - 例如,它可以是 Ember.run.later。
有人遇到同样的问题吗?我读过很多文章,我不敢相信拥有如此大社区的 Ember 竟然没有提供异步单元测试的方法。
如果有人有任何线索 - 请给我提示,因为我有点迷失在这里。目前我有两个想法:
我把 Controller 弄错了,Ember 不认为其中有任何异步操作。但即使我将异步调用移至服务 - 我在为它们编写单元测试时遇到了同样的问题。
我必须将我的功能分解为
readObject() { this.store.findRecord('myModel',1).then(this.actualReadObject.bind(this)); } actualReadObject(obj) { this.set('property1',obj.get('property2'); }
至少要让回调主体覆盖测试,但这意味着我永远不会在我的应用程序中获得 100% 的测试覆盖率。
提前感谢您提供任何线索。 :)
最佳答案
我遇到了类似的问题,正在查看 QUnit API - async我解决了。尝试以下操作:
// ... in your controller ...
readObject() {
return this.store.findRecord('myModel',1).then(function(obj) {
this.set('property1', obj.get('property2');
}.bind(this));
}
// ... in your tests, either with assert.async: ...
const done = assert.async(); // asynchronous test due to promises usage
Ember.run(function(){
subject.readObject().then(function(){
// once you reach this point you are sure your promise has been resolved
done();
});
});
// or without assert.async
let promise;
Ember.run(function(){
promise = subject.readObject();
});
return promise;
在单元测试的情况下,我还模拟其他依赖项,例如:store。
this.subject({
property1: null,
store: {
findRecord(modelName, id){
assert.equal(modelName, "myModel1");
assert.equal(id, 1);
return new Ember.RSVP.Promise(function(resolve){
resolve(Ember.Object.create({ property2: "a simple or complex mock" }));
})
}
}
});
我不确定第二种情况(没有 assert.async
的情况)。我认为它也会起作用,因为测试套件返回一个 promise 。这会被等待 promise 的 QUnit 识别。
关于javascript - 对 Ember Controller 中的异步函数进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36574693/