灰烬组件测试 - 当单元测试组件没有调用外部操作时如何操作?

时间:2017-04-12 21:06:23

标签: javascript testing ember.js ember-testing

我对Ember有点新,并试图测试一个寻呼机组件。简化组件如下所示:

export default Ember.Component.extend({
    index: 0,
    actions: {
        next() {
            this.incrementProperty('index');
        }
    }
});

我试图测试next()动作是否确实按预期增加了索引属性。我写了一个像这样的单元测试:

test('next should increment the index by 1', function (assert) {
  const component = this.subject();

  assert.equal(component.get('index'), 0, 'Index should be 0');

  component.get('actions').next();
  assert.equal(component.get('index'), 1, 'index should be 1');
});

但它失败并出现错误" this.incrementProperty不是函数"。调试,"这个"在测试中,当在next()函数内部时,不是组件的上下文 - 它是一个以next()作为唯一属性的对象。

我想知道这是不是因为我在测试中调用了nextPlace动作。我知道我可以编写一个集成测试,点击触发此操作的按钮并比较一些UI以确保它发生了变化,但是当我尝试测试的所有功能本身都按预期执行时,这似乎非常复杂。如果它是一个传递给这个组件的动作(关闭动作),我知道我可以在集成测试中设置一个虚函数,将它传递给组件,看看它是如何响应的。但是这个动作并没有调用传递给它的动作。

我意识到我测试的功能非常基本,但部分原因是要了解如何测试不会调用外部(到组件)操作的组件中的操作。

1 个答案:

答案 0 :(得分:2)

如果您没有表达不编写集成测试的动机,我建议您编写集成测试。 IMO,你的理由是有效的。我提出了3个启动单元测试的建议。

首先:不工作的原因是“component.get('actions').next在没有任何上下文的情况下获得对next函数的引用。因此this在该调用中无效。它有效,只需将组件绑定到它,如下所示:

component.get('actions').next.bind(component)();

但我不喜欢这个,因为它从它的上下文中提取next并再次绑定它。我们正在执行此bind项操作,因为我们知道next函数在其代码中引用了this

所以我的第二个建议就是“触发事件如何”。要触发它,请查看以下代码:

component.send('next');
IMO,这是更好的。我们不需要知道“接下来做什么”。我们只是在触发一个事件。

但这涉及到ember组件的生命周期。我们接受这种情况:有一个名为actions的特定哈希,我们可以通过send触发它。 (这完全没问题。)我们可以从actions分离doing something,而不是处理action handling。因此,您可以定义另一个函数来执行您需要的操作,并从操作处理程序中简单地调用它。 (好吧,在这种情况下,我们再次需要知道动作处理程序调用了什么函数。但这对我来说似乎更清楚。)如下所示:

next(){
  this.incrementProperty('index');
},
actions:{
  next(){
    this.next();
  }
}

您可以在this twiddle找到所有三种选择。

相关问题