服务未注入到组件的集成测试中



我有一个服务Foo(例如app/services/foo.js(:

import Ember from 'ember';
const FooService = Ember.Service.extend({
  myMethod() { ... }
});
export default FooService;

我在App的初始化器(例如app/initializers/foo.js(中初始化的,例如:

const initialize = function initialize(app) {
  app.inject('component', 'foo', 'service:foo');
}
const FooInitializer = {
  name: 'foo',
  initialize: initialize
}
export {initialize}
export default FooInitializer;

然后我有一个组件(例如app/components/my-component.js(,其中我使用此服务(我在这里不手动注入它,因为它已经注入了初始化器中的每个组件(:

import Ember from 'ember'
const MyComponent = Ember.Component.extend({
  actions:
    doSomething() { this.get('foo').myMethod(); }
});
export default MyComponent;

我为此组件创建了集成测试:

import { test, moduleForComponent } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
const fooStub = Ember.Service.extend({
  myMethod() {
    return true;
  }
});
moduleForComponent('my-component', 'Integration | Component | my-component', {
  integration: true,
  beforeEach() {
    this.register('service:foo', fooStub);
    // Calling inject puts the service instance in the context of the test,
    // making it accessible as "foo" within each test
    this.inject.service('foo', { as: 'foo' });
  }
});
test('it does something', function (assert) {
  this.render(hbs`{{my-component}}`);
  const spy = sinon.spy(this.get('foo'), 'myMethod');
  const $someElement = this.$().find('.some-element-within-my-component');
  // This element triggers `doSomething` action inside the component
  $someElement.click();
  assert.ok(spy.calledOnce, "myMethod was called within foo service");
});

运行此测试时,会引发错误:

TypeError: Cannot read property 'myMethod' of undefined

这意味着该服务没有被注入,甚至认为我将其手动注入了测试中。

我阅读了几次讨论,但是直到我碰到这一讨论之前,没有一个真正有用的,这暗示着我如果使用初始化器初始化而不是手动注入测试的组件,则ember可能不会将它们注入测试中。

因此,我试图将服务手动注入组件,测试工作。但是,这仅是部分解决方案,因为如果我必须手动将服务注入我的组件(并且有很多(只是为了使测试起作用,它就会完全破坏初始化器的目的。

你们中的任何一个都经历过这件事,如果是这样,我做错了什么,或者有能力做到这项工作,而无需手动将我的服务注入我拥有的每个组件中?也许这最终会在Ember中提交错误,但我首先想尝试stackoverflow,看看是否还有另一个解决方案。

afaik,初始化器和实例初始化器仅在acceptance-testing中运行。因此;初始化器内部进行的任何注射都必须用于integration-testing的手动处理。然而;恕我直言,这并不意味着您必须更改整个设计并手动将服务注入到组件中,以便测试应通过。为什么不仅在渲染组件时将创建的存根服务传递给组件?我的意思是以下:

this.render(hbs`{{my-component foo=foo}}`);

这只是将存根服务传递给组件。最后,您想要的是一种将服务从外部传递到组件的方法(通过初始化器,该功能不会自动在integration-testing中运行,或者通过模板运行(。这可能不是您想要的理想解决方案。但这足以使您的代码保持不太大的大惊小怪。

最新更新