简体   繁体   English

角度1.x / 2混合,业力测试不引导ng1应用程序

[英]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: 该代码的一些亮点:

  • I downgrade components differently for tests than for the app, so I made a DRY list of them in downgrade.ts 我为测试而不是应用程序降级组件的方式不同,所以我在downgrade.ts列出了它们的干燥列表
  • I downgrade components for the main app from 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()主应用程序的组件。
  • I showed the imports I needed to add to start integrating Angular components into my AngularJS tests. 我展示了我需要添加的导入以开始将Angular组件集成到我的AngularJS测试中。 You may need more/different ones depending eg on whether your tests are asynchronous, or you use Jasmine instead of Mocha. 您可能需要更多/不同的,具体取决于您的测试是否是异步,或者您使用Jasmine而不是Mocha。
  • At the beginning of each test that needs to use downgraded components, I "bootstrap" things with useAdaptedModule() instead of beforeEach(angular.mock.module("app")); 在需要使用降级组件的每个测试开始时,我使用useAdaptedModule()而不是beforeEach(angular.mock.module("app")); “引导”事物beforeEach(angular.mock.module("app"));
  • I import an alternative it from my helpers, which wraps the it provided by Mocha. 我进口替代it从我的助手,它包装了it的摩卡提供。 None of my tests are asynchronous; 我的测试都不是异步的; if you have some that are it may require tweaking. 如果你有一些它可能需要调整。 I do not know how it may need to be adapted for Jasmine. 我不知道它可能需要如何适应Jasmine。

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.

相关问题 Angular Ng1 / Ng2混合应用抛出“ No provider for $ scope”异常 - Angular Ng1/Ng2 hybrid app throwing 'No provider for $scope' exception 混合Angular 1.x + Angular 6应用程序,包含Angular 1.x中的vanilla JS和TS文件 - Hybrid Angular 1.x + Angular 6 App with both vanilla JS and TS files in Angular 1.x Angular 7 / 1.x混合应用程序可以支持HMR吗? - Can an Angular 7/1.x hybrid app support HMR? 为Hybrid Angular 2 / 1x app设置Karma配置 - Setting up Karma config for Hybrid Angular 2/1x app 将ng1模板放在由angular-cli构建的角度混合应用程序中的哪里? - Where to put ng1 templates in an angular hybrid application built by angular-cli? Angular2(混合模式)不能将指令降级为NG1(ES5) - Angular2 (hybrid mode) can't Downgrade Directive to NG1 (ES5) 单元测试中的 Angular 1.x 服务注入 - Angular 1.x service injection in unit tests Webpack + Karma + Typescript + Ng1:Uncaught SyntaxError:意外的令牌导入 - Webpack + Karma + Typescript + Ng1: Uncaught SyntaxError: Unexpected token import Angular 1.x,ES5 / ES6以及使用Karma进行测试 - Angular 1.x, ES5/ES6 and testing with Karma Bootstrapping Hybrid Angular 1 + 2应用程序 - Bootstrapping Hybrid Angular 1+2 Application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM