Ember.js: Модуль тестирует помощника, который имеет инъекцию зависимости?

В инициализаторе я вставляю объект в свой помощник, и он корректно работает в приложении.

Но при тестировании помощника с QUnit возникает следующая ошибка:

TypeError: undefined не является функцией.

Помощник не имеет доступа к инъецированному объекту, хотя при вызове App.__container__.lookup('myObject:main') в функции настройки модуля он возвращает объект.

Как я могу сделать эту работу? Класс тестирования основан на скрипке1, скрипка2.

Следующий пример в 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

Ответы

Ответ 1

Вы можете использовать сервис для обработки данных. Затем сервис может быть введен в помощник, который затем может быть легко протестирован.

Помощники в Ember 2.x теперь являются "реальными" объектами и могут иметь доступ к услугам.

Служба может выглядеть примерно так:

import Ember from 'ember';

export default Ember.Service.extend({
  profile: { 
    name: 'mary',
  },
});

Помощник получит данные из службы через инъекцию:

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();
  },
});

И наконец, unit test просто включит сервис 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, чтобы продемонстрировать.