Angular 1.x/2 Hybrid, тесты кармы, не начальная загрузка приложения ng1
В настоящее время у меня есть приложение Hybrid Angular (2.4.9 и 1.5.0), использующее angular-cli. В настоящее время при запуске нашего приложения мы можем правильно загрузить приложение 1.5:
// main.ts
import ...
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
angular.element(document).ready(() => {
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.body, ['myApp'], {strictDi: true});
});
});
Однако в нашем test.ts
файл:
// test.ts
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import ...;
declare var __karma__: any;
declare var require: any;
__karma__.loaded = function () {};
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
// I'm assuming that I need to call 'boostrapModule()' somehow here...
platformBrowserDynamicTesting()
);
const context = require.context('./', true, /\.spec\.ts$/);
context.keys().map(context);
__karma__.start();
Я не совсем уверен, как загрузить наше приложение 1.5 в тестовую среду, все, что я получил, это Module 'myApp' is not available!
, и мои навыки Google не смогли найти пример.
1 ответ
Я надеялся, что щедрость, которую я добавил прошлой ночью, будет означать, что я смогу войти этим утром, чтобы найти хорошее решение для меня. Увы, это не так. Поэтому вместо этого я провел целый день в кругу множества SO-ответов и проблем с github, заставляя его работать. Извините, я не отслеживал все, что помогло мне их зачислить, но вот мое решение. Это, вероятно, не идеально, но пока работает, поэтому я надеюсь, что это хорошее начало.
Эта проблема GitHub указывает на то, что downgradeComponent
не будет работать на данный момент, поэтому я пошел с тем, что я предполагаю, что это старая техника, использующая UpgradeAdapter
, Обратите внимание, что эта техника не использует initTestEnvironment
, Вот соответствующие фрагменты, с некоторыми пояснениями ниже:
// downgrade.ts:
export const componentsToDowngrade = {
heroDetail: HeroDetailComponent,
...
};
export function downgradeForApp() {
forOwn(componentsToDowngrade, (component, name) => {
app.directive(name!, downgradeComponent({ component }));
});
}
// main.ts:
downgradeForApp();
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then((platformRef) => {
...
});
// test.ts:
require("../src/polyfills.ts");
require("zone.js/dist/proxy");
require('zone.js/dist/sync-test');
require("zone.js/dist/mocha-patch");
// test-helper.ts
let upgradeAdapterRef: UpgradeAdapterRef;
const upgradeAdapter = new UpgradeAdapter(AppModule);
forEach(componentsToDowngrade, (component, selectorName) => {
angular.module("app").directive(
selectorName!,
upgradeAdapter.downgradeNg2Component(component) as any,
);
});
export function useAdaptedModule() {
beforeEach(() => {
upgradeAdapterRef = upgradeAdapter.registerForNg1Tests(["app"]);
});
}
export function it(expectation: string, callback: () => void) {
test(expectation, (done) => {
inject(() => { }); // triggers some kind of needed initialization
upgradeAdapterRef.ready(() => {
try {
callback();
done();
} catch (ex) { done(ex); }
});
});
}
// hero-detail.component.spec.ts
import { it, useAdaptedModule } from "test-helpers/sd-app-helpers";
describe("", () => {
useAdaptedModule();
it("behaves as expected", () => { ... });
});
Несколько основных моментов из этого кода:
- Я тестирую компоненты по-разному для тестов, чем для приложения, поэтому я сделал СУХОЙ их список в
downgrade.ts
- Я понижаю компоненты для основного приложения с
main.ts
позвонивdowngradeForApp()
как показано выше (используется с AOT для производственного комплекта), а такжеmain-jit.ts
, не показано выше (используется для разработки) - Я показал импорт, который мне нужно было добавить, чтобы начать интеграцию компонентов Angular в мои тесты AngularJS. Вам может понадобиться больше / разных в зависимости, например, от того, являются ли ваши тесты асинхронными, или вы используете Jasmine вместо Mocha.
- В начале каждого теста, в котором нужно использовать устаревшие компоненты, я "загружаю" вещи с
useAdaptedModule()
вместоbeforeEach(angular.mock.module("app"));
- Я импортирую альтернативу
it
от моих помощников, который оборачиваетit
предоставлено Мокко. Ни один из моих тестов не является асинхронным; если у вас есть что-то, это может потребовать настройки. Я не знаю, как это может быть необходимо адаптировать для Жасмин.
Предостережение: создание компонента должно происходить в пределах it
обратный вызов, так что это происходит в течение upgradeAdapterRef.ready(...)
, Пытаясь сделать это в течение beforeEach
слишком рано