[英]Angular 1.x/2 Hybrid, karma tests not bootstrapping ng1 app
I currently have a Hybrid Angular app (2.4.9 and 1.5.0) using angular-cli. 我目前使用angular-cli的Hybrid Angular应用程序(2.4.9和1.5.0)。 Currently, when running our application, we are able to bootstrap the 1.5 app correctly:
目前,在运行我们的应用程序时,我们能够正确引导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});
});
});
However, in our test.ts
file: 但是,在我们的
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();
I'm not exactly sure how to bootstrap our 1.5 application into the test environment, all I've gotten is Module 'myApp' is not available!
我不确定如何将我们的1.5应用程序引导到测试环境中,所有我得到的是
Module 'myApp' is not available!
, and my Google skills have failed trying to find an example. ,我的谷歌技能试图找到一个例子失败了。
I was hoping the bounty I added last night would mean I could log on this morning to a nice solution laid out for me. 我希望我昨晚补充的赏金意味着我今天早上可以登录为我提供一个很好的解决方案。 Alas, it did not.
唉,事实并非如此。 So instead I spent the day cruising around many SO answers and github issues getting it to work.
因此,我花了一天时间围绕许多SO答案和github问题开始工作。 I'm sorry I did not keep track of everything that helped me to credit them, but here is my solution.
对不起,我没有跟踪所有帮助我归功于他们的东西,但这是我的解决方案。 It is probably not ideal, but it is working so far so I hope it is a good start.
它可能不太理想,但它到目前为止工作,所以我希望这是一个良好的开端。
This github issue indicates that downgradeComponent
isn't going to work for now, so I went with what I assume is an older technique using UpgradeAdapter
. 这个github问题表明
downgradeComponent
暂时不起作用,所以我选择了使用UpgradeAdapter
的旧技术。 Note that this technique does not use initTestEnvironment
. 请注意,此技术不使用
initTestEnvironment
。 Here are the relevant snippets, with some explanations below: 以下是相关摘要,下面有一些解释:
// 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", () => { ... });
});
A few of the highlights from that code: 该代码的一些亮点:
downgrade.ts
downgrade.ts
列出了它们的干燥列表 main.ts
by calling downgradeForApp()
as shown above (used with AOT for a production bundle), and also main-jit.ts
, not shown above (used for development) downgradeForApp()
(与AOT一起用于生产包)以及main-jit.ts
(上面未显示(用于开发))从main.ts
downgradeForApp()
主应用程序的组件。 useAdaptedModule()
instead of beforeEach(angular.mock.module("app"));
useAdaptedModule()
而不是beforeEach(angular.mock.module("app"));
“引导”事物beforeEach(angular.mock.module("app"));
it
from my helpers, which wraps the it
provided by Mocha. it
从我的助手,它包装了it
的摩卡提供。 None of my tests are asynchronous; A caveat: Instantiating the component must happen within an it
callback so that it happens within upgradeAdapterRef.ready(...)
. 警告:实例化组件必须在
it
回调中发生,以便它在upgradeAdapterRef.ready(...)
。 Trying to do it within a beforeEach
is too soon. 试图在
beforeEach
做到这一点太早了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.