js:对有依赖注入的helper进行单元测试



在初始化器中,我将一个对象注入到我的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来演示

相关内容

  • 没有找到相关文章

最新更新