服务未注入组件的集成测试
Service not injected into component's integration test
我有一项服务Foo
(例如app/services/foo.js
):
import Ember from 'ember';
const FooService = Ember.Service.extend({
myMethod() { ... }
});
export default FooService;
我在应用程序的初始化程序中初始化(例如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
这意味着服务没有被注入,即使我认为我在测试中手动将它作为存根注入。
我读了几个讨论,但是 none 在我碰到 this one 之前真的很有帮助,这暗示我 Ember 可能不会将服务注入测试,如果它们使用初始化初始化程序,而不是手动注入到正在测试的组件中。
所以我尝试手动将服务注入到组件中,测试成功了。然而,这只是部分解决方案,因为如果我必须手动将服务注入我的组件(并且有很多)只是为了使测试工作,它会完全破坏初始化程序的目的。
你们中有人遇到过这种情况吗?如果有,是不是我做错了什么,或者是否有一种解决方法可以使这项工作无需手动将我的服务注入我拥有的每个组件?也许这最终会在 Ember 中提交错误,但我首先想尝试使用 Whosebug 看看是否还有其他解决方案。
据我所知,acceptance-testing
中只有 运行 个初始化器和实例初始化器。因此;对于 integration-testing
,在初始化器内部进行的任何注入都必须手动处理。然而;恕我直言,这并不意味着您必须更改整个设计并手动将服务注入组件才能通过测试。为什么不在渲染组件时将您创建的存根服务传递给组件?我的意思是:
this.render(hbs`{{my-component foo=foo}}`);
这只是将存根服务传递给组件。最后,您想要的是一种从外部将服务传递给组件的方法(通过初始化程序,它不会自动 integration-testing
中的 运行,或者通过模板)。这可能不是您想要的理想解决方案;但它足以让您的代码如您所愿,而无需大惊小怪。
我有一项服务Foo
(例如app/services/foo.js
):
import Ember from 'ember';
const FooService = Ember.Service.extend({
myMethod() { ... }
});
export default FooService;
我在应用程序的初始化程序中初始化(例如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
这意味着服务没有被注入,即使我认为我在测试中手动将它作为存根注入。
我读了几个讨论,但是 none 在我碰到 this one 之前真的很有帮助,这暗示我 Ember 可能不会将服务注入测试,如果它们使用初始化初始化程序,而不是手动注入到正在测试的组件中。
所以我尝试手动将服务注入到组件中,测试成功了。然而,这只是部分解决方案,因为如果我必须手动将服务注入我的组件(并且有很多)只是为了使测试工作,它会完全破坏初始化程序的目的。
你们中有人遇到过这种情况吗?如果有,是不是我做错了什么,或者是否有一种解决方法可以使这项工作无需手动将我的服务注入我拥有的每个组件?也许这最终会在 Ember 中提交错误,但我首先想尝试使用 Whosebug 看看是否还有其他解决方案。
据我所知,acceptance-testing
中只有 运行 个初始化器和实例初始化器。因此;对于 integration-testing
,在初始化器内部进行的任何注入都必须手动处理。然而;恕我直言,这并不意味着您必须更改整个设计并手动将服务注入组件才能通过测试。为什么不在渲染组件时将您创建的存根服务传递给组件?我的意思是:
this.render(hbs`{{my-component foo=foo}}`);
这只是将存根服务传递给组件。最后,您想要的是一种从外部将服务传递给组件的方法(通过初始化程序,它不会自动 integration-testing
中的 运行,或者通过模板)。这可能不是您想要的理想解决方案;但它足以让您的代码如您所愿,而无需大惊小怪。