Angular 4 Unit测试错误 - 无法在'XMLHttpRequest'上执行'send':无法加载'ng:///DynamicTestModule/LoginComponent.ngfactory.js'

时间:2017-08-07 16:03:14

标签: javascript angular unit-testing

我正在为我的组件编写一些单元测试,我收到了这个神秘的错误消息。我在Angular 2 unit testing - getting error Failed to load 'ng:///DynamicTestModule/module.ngfactory.js'找到了类似的问题,但答案并没有帮助我解决我的问题。我很有棱角4.3.2

这是我正在编写测试的组件:

import {Component} from '@angular/core';
import {Router} from '@angular/router';

import {NotificationService} from '../common/notification/notification.service';
import {SessionService} from '../common/session/session.service';
import {Login} from './login.model';

@Component({
             selector: 'cc-login-form',
             templateUrl: './login.component.html',
             styleUrls: ['./login.component.scss'],
           })
export class LoginComponent {
  model: Login = new Login('', '');

  constructor(private sessionService: SessionService,
              private router: Router,
              private notificationService: NotificationService) {
  }

  onSubmit() {
    this.sessionService
        .login(this.model.email, this.model.password)
        .subscribe(
          sessionInfo => {
            this.notificationService.showSuccess('notification.successfully.logged.in');
            this.router.navigate([`/cc/list`]);
          },
          error => this.notificationService.showError('notification.invalid.login')
        );
  }
}

这是测试文件:

import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from '@angular/forms';
import {Router} from '@angular/router';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import {NotificationService} from '../common/notification/notification.service';
import {NotificationServiceStub} from '../common/notification/tests/NotificationServiceStub';
import {SessionService} from '../common/session/session.service';
import {SessionServiceStub} from '../common/session/tests/SessionServiceStub';
import {RouterStub} from '../common/tests/RouterStub';
import {TranslateServiceStub} from '../common/translate/tests/TranslateServiceStub';

import {LoginComponent} from './login.component';

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
                                     imports: [
                                       FormsModule,
                                       TranslateModule
                                     ],
                                     declarations: [LoginComponent],
                                     providers: [
                                       {provide: SessionService, useClass: SessionServiceStub},
                                       {provide: Router, useClass: RouterStub},
                                       {provide: NotificationService, useClass: NotificationServiceStub},
                                       {provide: TranslateService, useClass: TranslateServiceStub},
                                     ]
                                   })
           .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });
});

运行测试时,我在chrome控制台上获得以下内容:

zone.js:2642 XMLHttpRequest cannot load ng:///DynamicTestModule/LoginComponent.ngfactory.js. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
(anonymous) @ zone.js:2642
zone.js:195 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'ng:///DynamicTestModule/LoginComponent.ngfactory.js'.
    at http://localhost:9876/_karma_webpack_/webpack:/Users/pedrompg/Documents/quandoo/fe/chains-center/~/zone.js/dist/zone.js:2642:1
    at XMLHttpRequest.proto.(anonymous function) [as send] (

任何可以帮助我吗?

编辑 - 1 这是服务/存根实现

SessionServiceStub

export class SessionServiceStub implements ISessionService {
  login(login: string, password: string): Observable<any> {
    return Observable.of({merchantId: 123});
  }

  logout(): Observable<any> {
    throw new Error('Method not implemented.');
  }

  validateSessionToken(): Observable<any> {
    throw new Error('Method not implemented.');
  }
}

SessionService

@Injectable()
export class SessionService implements ISessionService {

  constructor(private http: CcHttpClient, private router: Router, private localSessionService: LocalSessionService) {
  }

  login(login: string, password: string): Observable<any> {
    return this.http.post(`api/sessions`, {login: login, password: password}).map((res: Object) => {
      this.localSessionService.createSession(res);
      return res;
    });
  }
}

RouterStub

export class RouterStub {
  navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
    return Promise.resolve(true);
  };
}

TranslationServiceStub

export class TranslateServiceStub {
  instant(key: string | Array<string>, interpolateParams?: Object): string | any {
    return 'translation';
  };
}

NotificationServiceStub

export class NotificationServiceStub implements INotificationService {
  showToast(type, text, title, defaultTitle): Promise<Toast> {
    return Promise.resolve(null);
  }

  showSuccess(msg, title?): Promise<Toast> {
    return Promise.resolve(null);
  }

  showError(msg, title?): Promise<Toast> {
    return Promise.resolve(null);
  }
}

编辑2 将我的TestBed配置更改为以下内容删除了错误,但带来了一个新错误:

beforeEach(async(() => {
    TestBed.configureTestingModule({
                                     imports: [
                                       FormsModule,
                                       HttpClientModule,
                                       TranslateModule.forRoot({
                                                                 loader: {
                                                                   provide: TranslateLoader,
                                                                   useFactory: HttpTranslateLoaderFactory,
                                                                   deps: [HttpClient]
                                                                 }
                                                               })
                                     ],
                                     declarations: [LoginComponent],
                                     providers: [
                                       {provide: SessionService, useClass: SessionServiceStub},
                                       {provide: Router, useClass: RouterStub},
                                       {provide: NotificationService, useClass: NotificationServiceStub},
                                     ]
                                   })
           .compileComponents();
  }));

现在错误消息是

TypeError: Cannot read property 'assertPresent' of undefined
        at resetFakeAsyncZone home/pedrompg/Documents/quandoo/fe/chains-center/~/@angular/core/@angular/core/testing.es5.js:304:1)
        at Object.<anonymous> home/pedrompg/Documents/quandoo/fe/chains-center/~/@angular/core/@angular/core/testing.es5.js:1001:1)
        at ZoneQueueRunner.webpackJsonp.../../../../zone.js/dist/jasmine-patch.js.jasmine.QueueRunner.ZoneQueueRunner.execute home/pedrompg/Documents/quandoo/fe/chains-center/~/zone.js/dist/jasmine-patch.js:132:1)

这个功能发生了什么:

function resetFakeAsyncZone() {
    _fakeAsyncTestZoneSpec = null;
    ProxyZoneSpec.assertPresent().resetDelegate(); //ProxyZoneSpec is undefined here for whatever reason
}

4 个答案:

答案 0 :(得分:29)

这是Angular Cli 1.2.2或更新的问题。使用--sourcemaps=false运行测试,您将收到正确的错误消息。

  

ng test --sourcemaps = false

修改

的简写是:

  

ng test -sm = false

请在此处查看详细信息:https://github.com/angular/angular-cli/issues/7296

答案 1 :(得分:6)

我刚遇到这个错误,问题就是我的嘲笑。 在component.ngOnInit我使用this.route.paramMap.subscribe(...) 其中route是ActivatedRoute实例

在我的测试中,我提供了这样的模拟服务:

providers: [
    { provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } }, paramMap: Observable.of({get: () => 1}) } }
]

事实上我错过了模拟paramMap方法

然后我修复它添加像这样的paramMap属性

{{1}}

然后我不再有这个愚蠢的错误。

所以对你来说,我希望SessionServiceStub类不完整或错误。它是否获得返回Observable的登录方法?

如果不是问题,您可以查看NotificationServiceStub

您应该使用调试器(使用Webstorm,它可以逐步调试)来帮助您。

答案 2 :(得分:1)

这几个小时都在追逐这个。最后发现问题只是我导入了HttpClientModule,而不是HttpClient

import { HttpClient, HttpClientModule } from '@angular/common/http';

所有这些CORS错误和'[Script Loader]', DOMException{stack: 'Error: Failed to execute 'send' on 'XMLHttpRequest'内容,它归结为没有HttpClient!

答案 3 :(得分:1)

我在使用angular-cli 6时遇到了相同的问题,因此要获得正确的错误消息,应使用以下内容:

ng test --source-map=false

也许会帮助某人:)。