2017-06-26 73 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關於這個東西,因爲它試圖讓這個運行的人真的很困惑。無論如何要幫助。 –

相關問題