如何在 Ember.js 中测试组件方法?

How to test component methods in Ember.js?

我有一个组件只有一个方法和服务,它可以 运行 对某些组件起作用。

export default Ember.Component.extend({
  foo: false,

  bar() {
    this.set('foo', true);
  },

  someService: Ember.inject.service('some-service'),

  didInsertElement: function () {
    const someService = this.get('someService');
    someService.registerComponent(this);
  },
});

export default Ember.Service.extend({
  components: [],
  registerComponent: function (component) {
    let components = this.get('components');
    components.push(component);
  },
  runBar(index) {
    let components = this.get('components');
    components[index].bar();
  }
});

1) 如何为 bar() 方法编写测试?

2) 以及如何为该服务编写测试?

3) 或者我该如何重构这种方法?

我会尽量按顺序回答你的问题;在开始之前,请查看以下 twiddle 我为您准备的内容。我刚刚复制了您的组件和服务定义;但还为组件添加了 willDestroyElement 并为服务添加了 unregisterComponent 以进行必要的清理以从服务中删除组件。请注意要进行的清理工作;如果你根本不考虑它,你会 运行 陷入大麻烦。关于您的问题;

1) 不得直接调用bar方法进行组件测试。您需要做的是渲染组件;检查一些断言;并调用服务的 runBar 方法,以便在集成测试中调用组件的 bar 方法。据我了解,这是您脑海中的场景。请查看我上面提供的 twiddle 中的 my-component-test.js 文件。这个测试的关键部分可能是

 Ember.run(()=>Ember.getOwner(this).lookup('service:some-service').runBar(0));

代码片段。 Ember.getOwner(this).lookup() 使您能够获取服务;请注意,您需要提供全名 (service:some-service) 才能获取它。它处于 运行 循环中;因为它应该具有异步影响并且 Ember 会警告您。反正;我想测试本身很简单;因为组件所做的只是将 foo 属性 打印到屏幕上,并且在调用服务的 runBar 方法时 属性 从初始值设置为 true false.

2) 用于测试服务;你可以写一个单元测试,这就是我在胡闹中所做的。注意;您不需要实际组件来注册服务;所以我使用了存根组件(只是 Ember.Object 中的虚拟实例)。我相信其余的很容易理解。我只是调用服务的 runBar 方法并检查预期的断言。

3) 现在这是个难题;因为仅从您提供的代码片段中很难看出您进行此类设计的意图。尽管如此;我对重构的评论如下:请尽可能避免将组件注册到其他构造(父组件、子组件、控制器、路由、服务等)。恕我直言,组件的内部函数只能由组件本身调用。组件的接口应该是组件要触发的事件(我的意思是从外部提供的动作)和从外部传递的属性。我不主张在任何情况下都应避免您的设计;但只有在没有其他选择的情况下才必须小心使用。主要原因是;这样设计的代码的可追溯性应该会成为一场噩梦。任何有权访问该服务的人都应该更新它一无所知的组件(已注册到该服务)。这是我非常不喜欢的事情。我的建议是依赖定义良好的组件 API,而不是四处传递它并导致从不相关的地方对其进行更新。

这已经很久了post;希望对你有帮助。