Angular 4 单元测试错误 - 无法在"XMLHttpRequest"上执行'send':无法加载'ng:///DynamicTestModule/LoginComponent.ngfac



我正在为我的组件编写一些单元测试,并收到此神秘的错误消息。我在 Angular 2 单元测试中发现了一个类似的问题 - 收到错误无法加载"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 这是服务/存根实现

会话服务存根

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.');
}
}

会话服务

@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;
});
}
}

路由器存根

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

翻译服务存根

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

通知服务存根

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
}

这是Angular Cli版本1.2.2或更高版本的问题。 使用--sourcemaps=false运行测试,您将获得正确的错误消息。

在角度 4-5 中

  • ng test --sourcemaps=false
    
  • ng test -sm=false
    

在角度 6+ 中

  • ng test --source-map=false
    

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

我刚刚遇到了这个错误,问题是我的模拟。 在component.ngOnInit中,我使用了this.route.paramMap.subscribe(...( 其中路由是激活路由实例

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

providers: [
{ provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } } } }
]

事实上,我错过了嘲笑参数映射方法

然后我修复它,添加一个参数映射属性,如下所示

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

那我就没有这个愚蠢的错误了。

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

如果不是问题,您可以检查通知服务存根

您应该使用调试器(使用 Webstorm 很容易逐步调试(来帮助您。

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

ng test --source-map=false

也许它会帮助某人:).

已经追了几个小时了。最后发现问题只是我导入了HttpClientModule,而不是HttpClient

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

所有这些CORS错误,以及'[Script Loader]', DOMException{stack: 'Error: Failed to execute 'send' on 'XMLHttpRequest'的东西,归根结底就是没有HttpClient!

最新更新