2014-02-27 46 views
5

我想在我的Ember應用程序單元測試中測試一個組件,直到現在,除了我處於斷言需要呈現它的模板的位置之外,所有這一切都很好。在EmberJS中單元測試組件的正確方法

這樣做通常一個會叫

var comp = App.SomeNamedComponent.create(); 
var comp.appendTo(App.rootElement); 

不過,雖然這將創建一個組件的基本元素,它不會呈現它的模板。經過一些研究,我最終發現在組件上既沒有設置templateName也沒有設置template屬性。所以我決定自己設置templateName,但是後來它抱怨說A Component must have a parent view in order to yield.

然後我決定創建一個使用該組件與模板測試的另一個自定義視圖,但我不能訪問該組件的實例...

我需要訪問的實例,使斷言,我需要讓它的模板呈現,因爲一些屬性是根據模板中某些元素的CSS來計算的。

回答

20

這是我的典型測試的組件當不需要的容器(特別是當被提供給該組件的模板和佈局編程):

Ember.testing = true; 

MyAwesomeComponent = Ember.Component.extend(); 

function createComponent(componentName, factory, options) { 
    if (typeof options.template === 'string') { 
    options.template = Ember.Handlebars.compile(options.template); 
    } 

    if (typeof options.layout === 'string') { 
    options.layout = Ember.Handlebars.compile(options.layout); 
    } 

    if (options.template && !options.layout) { 
    options.layout = options.template; 
    delete options.template; 
    } 

    var component = factory.create(options); 

    Ember.run(function(){ 
    component.appendTo('#qunit-fixture'); 
    }); 

    return component; 
} 

module('component testing sample'); 

test('a component with template', function(){ 
    var options = {layout: 'woot woot{{fullName}}'}; 

    var component = createComponent('my-awesome', MyAwesomeComponent, options); 

    equal(component.$().text(), 'woot woot'); 
}); 

test('a component with custom options and a template', function(){ 
    var options = { 
    fullName: 'Robert Jackson', 
    layout: '{{fullName}}' 
    }; 

    var component = createComponent('my-awesome', MyAwesomeComponent, options); 

    equal(component.$().text(), 'Robert Jackson'); 
}); 

查看示例JSBin


如果你需要/希望能夠查找您可以使用類似以下(它創建一個孤立的容器)模板:

Ember.testing = true; 

MyAwesomeComponent = Ember.Component.extend(); 

function isolatedContainer() { 
    var container = new Ember.Container(); 

    container.optionsForType('component', { singleton: false }); 
    container.optionsForType('view', { singleton: false }); 
    container.optionsForType('template', { instantiate: false }); 
    container.optionsForType('helper', { instantiate: false }); 

    return container; 
} 

function createComponent(componentName, factory, options) { 
    var fullName = 'component:' + componentName, 
     templateFullName = 'template:components/' + componentName; 

    container.register(fullName, factory); 

    if (container.has(templateFullName)) { 
    container.injection(fullName, 'layout', templateFullName); 
    } 

    var Component = container.lookupFactory(fullName), 
     component = Component.create(options); 

    Ember.run(function(){ 
    component.appendTo('#qunit-fixture'); 
    }); 

    return component; 
} 

function registerTemplate(name, template){ 
    if (typeof template !== 'function') { 
    template = Ember.Handlebars.compile(template); 
    } 

    container.register('template:' + name, template); 
} 

var container; 

module('component testing sample', { 
    setup: function(){ 
    container = isolatedContainer(); 
    }, 
    teardown: function(){ 
    Ember.run(container, 'destroy'); 
    } 
}); 

test('a component with template', function(){ 
    registerTemplate('components/my-awesome', 'woot woot{{fullName}}'); 

    var component = createComponent('my-awesome', MyAwesomeComponent); 

    equal(component.$().text(), 'woot woot'); 
}); 

test('a component with custom options and a template', function(){ 
    registerTemplate('components/my-awesome', '{{fullName}}'); 

    var component = createComponent('my-awesome', MyAwesomeComponent, {fullName: 'Robert Jackson'}); 

    equal(component.$().text(), 'Robert Jackson'); 
}); 

的容器版本JSBin

相關問題