在初始化器中,我将一个对象注入到我的helper中,它在App中正常工作。
但是当使用QUnit测试helper时,我得到以下错误:
TypeError: undefined不是函数。
helper不能访问被注入的对象,尽管在模块的setup函数中调用App.__container__.lookup('myObject:main')
时,它确实返回该对象。
我怎样才能使它工作?测试类基于fiddle1、fiddle2。
下面的CoffeeScript示例显示了我的问题:
App = undefined
entered = false
initializedCount = 0
module 'testing',
setup: ->
App = startApp()
teardown: ->
Ember.run(App, 'destroy')
Ember.Application.initializer({
name: "person",
initialize: (container, application) ->
initializedCount++;
person = {
name: "Mary"
}
container.register('person:main', person, {instantiate: false});
container.injection('helper', 'person', 'person:main');
});
createView = (template, context) ->
context = {} unless context
View = Ember.View.extend(
controller: context
template: Ember.Handlebars.compile(template)
)
View.create()
append = (view) ->
Ember.run ->
view.appendTo "#ember-testing"
return
return
Ember.Handlebars.helper "upcase", (value) ->
person = @get('person'); # <-- test fails here
value += person.name;
value.toUpperCase()
Ember.testing = true
test('non-redirect route /third', ->
equal(initializedCount, 2, 'initializer ran');
App.reset();
equal(initializedCount, 3, 'initializer ran');
App.reset();
equal(initializedCount, 4, 'initializer ran');
);
test "a handlebars helper", ->
view = createView("{{upcase 'something'}}")
append view
equal view.$().text(), "SOMETHING MARY"
return
在最近的Ember中,moduleFor()
语法已经被弃用了,但是this.owner.lookup()
方法是控制器和其他实例的迁移路径,它似乎没有为helper返回一个带有上下文的实例。
我找不到任何关于测试依赖关系的帮助器的文档,但是在咨询了Ember自己的测试之后,我发现Application.factoryFor()
似乎做到了这一点:
import { module, test } from 'qunit'
import { setupTest } from 'ember-qunit'
module('Unit | Helper | example-helper', function (hooks) {
setupTest(hooks)
let exampleHelper
hooks.beforeEach(function () {
exampleHelper = this.owner.factoryFor('helper:example-helper').create()
})
test('base', function (assert) {
assert.equal(exampleHelper.compute([params]), 'expected result')
})
})
使用factoryFor().create()
确实构建了一个具有适当上下文和注入依赖的实例。我不知道这是否是推荐的方法,但它似乎做了我想要的!
您可以考虑使用服务来处理数据。然后可以将服务注入到helper中,这样就可以很容易地进行单元测试。
烬2的助手。X现在是"真实的"对象,并且可以访问服务。
服务可能看起来像这样:
import Ember from 'ember';
export default Ember.Service.extend({
profile: {
name: 'mary',
},
});
helper将通过注入从服务接收数据:
import Ember from 'ember';
export default Ember.Helper.extend({
person: Ember.inject.service(), // <-- here
compute(params) {
const text = params[0];
const name = this.get('person.profile.name');
const phrase = `${text} ${name}`;
return this.upperCase(phrase);
},
upperCase(str) {
return str.toUpperCase();
},
});
最后,单元测试只包括Person服务作为必需的 need
:
import { moduleFor, test } from 'ember-qunit';
moduleFor('helper:upper-case', {
needs: [ 'service:person' ], // <-- here
});
test('when the upperCase helper is used', function(assert) {
const helper = this.subject();
const result = helper.compute([ 'goodbye' ]);
const expected = 'GOODBYE MARY';
assert.equal(result, expected,
'...the dependency is injected and all are uppercased');
});
此外,该服务还可以通过初始化器注入到整个应用程序中,就像这样:
export function initialize(application) {
application.inject('controller', 'person', 'service:person');
application.inject('component', 'person', 'service:person');
application.inject('route', 'person', 'service:person');
// etc.
}
export default {
name: 'person',
initialize,
};
我已经创建了一个Ember Twiddle来演示