Ответ 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", () => { ... });
});
Несколько основных моментов этого кода:
- Я отказываюсь от компонентов по-разному для тестов, чем для приложения, поэтому я сделал DRY-список из них в
downgrade.ts
- Я снижаю компоненты основного приложения из
main.ts
, вызываяdowngradeForApp()
, как показано выше (используется с AOT для производственного пакета), а такжеmain-jit.ts
, не показанный выше (используется для разработки) - Я показал импорт, который мне нужно добавить, чтобы начать интеграцию компонентов Angular в мои тесты AngularJS. Возможно, вам понадобится больше/разные, например, о том, являются ли ваши тесты асинхронными, или вы используете Jasmine вместо Mocha.
- В начале каждого теста, который должен использовать пониженные компоненты, я "загружаю" вещи с помощью
useAdaptedModule()
вместоbeforeEach(angular.mock.module("app"));
- Я импортирую альтернативный
it
из моих помощников, который обертываетit
, предоставленный Mocha. Ни один из моих тестов не асинхронен; если у вас есть такие, которые могут потребовать настройки. Я не знаю, как это может понадобиться для Jasmine.
Предостережение. Создание экземпляра компонента должно происходить в обратном вызове it
, так что это происходит в upgradeAdapterRef.ready(...)
. Попытка сделать это в beforeEach
слишком скоро.