setApplication нарушает контекст теста ember-qunit - PullRequest
1 голос
/ 03 октября 2019

Я недавно обновил приложение Ember с 2.18 до 3.13, которое прошло гладко. Сегодня я попытался добавить приемочный тест в первый раз (до этого были только интеграционные / модульные тесты), но тест не прошел в первой строке:

import { module, test } from "qunit";
import { visit, currentURL } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";

module("Acceptance | some route", function(hooks) {
  setupApplicationTest(hooks);

  test("visiting /some-route", async function(assert) {
    await visit("/some-route"); // <----- error thrown here

    assert.equal(currentURL(), "/some-route");
  });
});

Я вижу пару ошибок (вэтот порядок):

Source:     
TypeError: Cannot read property 'lookup' of undefined
    at Object.initialize (http://localhost:4200/assets/my-app.js:10312:28)
    at http://localhost:4200/assets/vendor.js:61627:21
    at Vertices.each (http://localhost:4200/assets/vendor.js:80243:9)
    at Vertices.walk (http://localhost:4200/assets/vendor.js:80157:12)
    at DAG.each (http://localhost:4200/assets/vendor.js:80087:22)
    at DAG.topsort (http://localhost:4200/assets/vendor.js:80095:12)
    at Class._runInitializer (http://localhost:4200/assets/vendor.js:61653:13)
    at Class.runInitializers (http://localhost:4200/assets/vendor.js:61625:12)
    at Class._bootSync (http://localhost:4200/assets/vendor.js:59923:14)
    at Class.boot (http://localhost:4200/assets/vendor.js:59890:14)


Source:     
Error: Cannot call `visit` without having first called `setupApplicationContext`.
    at visit (http://localhost:4200/assets/test-support.js:44177:13)
    at Object._callee$ (http://localhost:4200/assets/tests.js:23:47)
    at tryCatch (http://localhost:4200/assets/vendor.js:12365:40)
    at Generator.invoke [as _invoke] (http://localhost:4200/assets/vendor.js:12591:22)
    at Generator.prototype.<computed> [as next] (http://localhost:4200/assets/vendor.js:12417:21)
    at asyncGeneratorStep (http://localhost:4200/assets/tests.js:6:105)
    at _next (http://localhost:4200/assets/tests.js:8:196)
    at http://localhost:4200/assets/tests.js:8:366
    at new Promise (<anonymous>)
    at Object.<anonymous> (http://localhost:4200/assets/tests.js:8:99)

После небольшого копания похоже, что что-то неправильно устанавливает контекст теста. Это просто пустой объект:

enter image description here

Таким образом, isApplicationTestContext(context) возвращает false и выдается вторая ошибка. Я предполагаю, что первая ошибка выдается, потому что приложение имеет некоторые инициализаторы, которые выполняют поиск.

Чтобы добавить этот приемочный тест, я также обновил файл test-helper.js до следующего:

import Application from "../app";
import config from "../config/environment";
import { setApplication } from "@ember/test-helpers";
import { start } from "ember-qunit";

setApplication(Application.create(config.APP));

start();

При использовании вышеуказанного файла все тесты не пройдены, поэтому кажется, что setApplication вызывает неверный контекст теста? Старый файл test-helper.js выглядел примерно так:

import resolver from "./helpers/resolver";
import { setResolver } from "@ember/test-helpers";
import { start } from "ember-cli-qunit";

setResolver(resolver);
start();

Я пытался повторно добавить вызов setResolver, но это не имеет значения. Кто-нибудь еще сталкивался с этими проблемами с новым синтаксисом ember-qunit или, возможно, мог видеть, что я делаю неправильно? Кроме того, я установил autoboot = false; в файле environment.js, который не имел значения. Набор тестов также имеет один или два теста, которые все еще написаны в старом синтаксисе ember-qunit. Любая помощь будет оценена!

1 Ответ

0 голосов
/ 05 октября 2019

Во-первых, несколько предысторий:

Наше приложение использует стороннюю библиотеку для метрик и другую стороннюю библиотеку для флагов функций. Каждая библиотека имеет свой собственный сервис, но нам нужно, чтобы сервис метрик был инициализирован до того, как сервис флагов объектов может быть инициализирован, потому что мы хотим связать аналитические пользовательские данные, чтобы получить правильные флаги объектов для каждого пользователя. Проверки флагов функций выполняются во всем приложении, поэтому возникло условие состязания между моментом, когда будет выполняться проверка флагов функций и когда файл аналитики был загружен в тег сценария на веб-странице.

Теперь решение:

Причина появления этой ошибки:

Source:     
TypeError: Cannot read property 'lookup' of undefined
    at Object.initialize (http://localhost:4200/assets/my-app.js:10312:28)
    at http://localhost:4200/assets/vendor.js:61627:21
    at Vertices.each (http://localhost:4200/assets/vendor.js:80243:9)
    at Vertices.walk (http://localhost:4200/assets/vendor.js:80157:12)
    at DAG.each (http://localhost:4200/assets/vendor.js:80087:22)
    at DAG.topsort (http://localhost:4200/assets/vendor.js:80095:12)
    at Class._runInitializer (http://localhost:4200/assets/vendor.js:61653:13)
    at Class.runInitializers (http://localhost:4200/assets/vendor.js:61625:12)
    at Class._bootSync (http://localhost:4200/assets/vendor.js:59923:14)
    at Class.boot (http://localhost:4200/assets/vendor.js:59890:14)

в том, что в приложении есть инициализатор приложения, который использовал частные API Ember для выполнения поиска из контейнера. Инициализатор выполнил поиск, чтобы неявно инициализировать службу метрик перед извлечением аналитических данных, а затем инициализировать службу флагов объектов.

export function initialize(application) {
  const container = application.__container__; // <-- undefined
  const lookup = container.lookup.bind(application.__container__); // <-- error!
  ...
}

Что странно, - приведенный выше код работает в средах development и production,Это изменение, по-видимому, является результатом устаревания / перестановки внутренних Ember API, особенно связанных с контейнером. См. Эту страницу для получения дополнительной информации .

Чтобы получить доступ к контейнеру в инициализаторе приложения, это должно быть сделано из экземпляра приложения (т. Е. Инициализатора экземпляра). Это могло бы быть приемлемым решением, но я не был уверен на 100%, могли бы мы отложить готовность приложения от инициализатора экземпляра приложения.

Для получения дополнительной информации об инициализаторах экземпляра приложения см. Здесь .

Вместо этого код был перемещен в хук маршрута приложения beforeModel(). Я также добавил инициализатор экземпляра для службы метрик, что привело к более быстрому времени загрузки приложения.

После перемещения кода инициализатора в маршрут приложения приложение теперь успешно создается, и приемочные тесты работают как чудо. :)

...