我的一些验收测试(涉及操作)在与所有其他测试一起运行时随机失败,但在隔离运行时从未失败。
Error: Assertion Failed: calling set on destroyed object
在我的动作中被触发
我在以用户身份使用表时没有遇到任何问题,所以这些问题只出现在测试中。所以我不确定这是否只是因为每次运行后应用程序没有正确销毁。
我能以某种方式理解为什么物体即将被摧毁,或者哪些观察者正在阻挡它吗?
foos/index/route.js
startFoo(foos) {
foos.forEach(function(foo) {
foo.set('status', 'active');
foo.save();
});
},
这个action
被传递到一个组件(表),该组件显示了foo
模型的列表。可以选择每一行,这样可以将该行的foo
模型添加到此表组件的属性selectedRows
中。
组件/my-table/table.js
visibleColumns: Ember.A(),
selectedRows: Ember.A(),
selectRow(row) {
let selectedRows = this.get('selectedRows');
if (selectedRows.contains(row)) {
selectedRows.removeObject(row);
} else {
selectedRows.addObject(row);
}
},
isSelected(row) {
return this.get('selectedRows').contains(row);
},
components/my table/header/template.hbs
action.cb
是函数startFoo
<button {{action action.cb table.selectedRows}}>
{{im-icon icon=action.icon}}
</button>
表组件是非常模块化的,因此它有header
、columns
、cells
、rows
,为了共享状态(如所选行),我使用了一个Ember.Object
,它被传递到表组件的所有部分(这可能是问题所在?!!?)
components/my table/row/component.js
isSelected: computed('table.selectedRows.[]', {
get(/*key*/) {
return this.get('table').isSelected(this.get('content'));
},
set(/*key, value*/) {
this.get('table').selectRow(this.get('content'));
return this.get('table').isSelected(this.get('content'));
},
}),
组件/我的表/行/模板.hbs
content
是foo
型
<td class="shrink">{{input type='checkbox' checked=isSelected}}</td>
{{#each table.visibleColumns as |column|}}
{{my-table/cell content=content column=column}}
{{/each}}
测试
设置和拆卸是ember-cli
默认
moduleForAcceptance('Acceptance | Foos');
test('click on action start changes state to active', function(assert) {
server.create('foo', {
status: 'paused'
});
// This is an ember-page-object
fooPage
.visit()
.selectFoo()
.clickStart();
andThen(function() {
assert.equal(fooPage.foos(1).status(), 'active', 'runs action');
});
});
设置前检查isDestroyed
应该可以完成
isSelected: computed('table.selectedRows.[]', {
get(/*key*/) {
return this.get('table').isSelected(this.get('content'));
},
set(/*key, value*/) {
if (this.get('isDestroyed')) {
return;
}
this.get('table').selectRow(this.get('content'));
return this.get('table').isSelected(this.get('content'));
},
}),