2017-06-26 75 views
0

我有一个服务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 

,这意味着该服务没有被注入,甚至以为我注入它在手动测试中作为存根。

我读了几个讨论,但没有一个是真正有用的,直到我碰到this one这暗示我Ember可能不会将服务注入到测试中,如果它们使用初始化程序初始化并且不是手动注入到正在测试的组件中。

所以我试图手动注入服务到组件和测试工作。然而,这只是部分解决方案,因为如果我必须手动将服务注入到我的组件(并且有很多),以便使测试正常工作,它完全破坏了初始化程序的用途。

有没有人遇到过这种情况,如果有的话,有没有我做错了或有没有解决方法使这项工作无需手动将我的服务注入到我拥有的每个组件中?也许这最终会在Ember中提交一个错误,但我首先想尝试使用stackoverflow来查看是否有另一个解决方案。

回答

1

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

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

这只是将存根服务传递给组件。最后,你想要的是一种将服务从外部传递到组件的方式(通过初始化程序,它不会自动运行在integration-testing中,或通过模板运行)。这可能不是您想要的理想解决方案;但它足以让您的代码随心所欲,而不必担心。

+0

工程像魅力。谢谢!顺便说一句,你能指点我到一个地方,它记录了初始化器和实例初始化器只在验收测试中运行吗?谢谢。 –

+0

有关在Ember中测试的文档是不够的,我写的有关初始化程序的内容甚至都不正确。我根据自己的记忆,依靠过去的经验写下它:)))但我确信;他们不运行集成测试:))) – alptugd

+0

他们肯定不会运行,否则这将工作。好吧,我想我应该通知Ember关于这个东西,因为它试图让这个运行的人真的很困惑。无论如何要帮助。 –

相关问题