Angular 6 Error: Cannot make XHRs from within a fake async test. Request URL: https://mlj0xk2yy.com/latest/static/videos

Angular 6 Error: Cannot make XHRs from within a fake async test. Request URL: https://mlj0xk2yy.com/latest/static/videos

你能告诉我如何解决这个问题吗?

login.component.spec.ts

 const mockModel = {
        url: 'login',
        model: {
            handle: 'test@test.com',
            password: '123456789'
        }
    }

    export class HttpCommonServiceMock {

        public post(url: any, model: any): any { }

    }

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

 beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [ReactiveFormsModule, FormsModule, CoreModule, HttpModule],
            declarations: [],
            providers: [
                { provide: APP_BASE_HREF, useValue: '/' },
                { provide: HttpCommonService, useClass: HttpCommonServiceMock },
              ]
        });
     }));

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

 it('should create component', () => {
        expect(component instanceof LoginComponent).toBe(true);//This is working fine
    });

it('a successful login', fakeAsync(() => {//This is NOT working

 let httpCommonService = fixture.debugElement.injector.get(HttpCommonService);

        let httpCommonResponse = {
            isValid: true
        };

        spyOn(httpCommonService,'post').and.returnValue(of(httpCommonResponse));

        component.login(mockModel.model);

        tick();

        expect(httpCommonResponse).toBe(true);
    }));


});

login.component.ts

@Component({
  selector: "login",
  templateUrl: "./login.component.html"
})
export class LoginComponent implements OnInit {
  form: FormGroup;
  message: string;
  constructor(private fb: FormBuilder,
    private router: Router,
    private notification: SiteNotificationService,
    private session: UserSessionService,
    private httpCommonService: HttpCommonService,
    private getStaticComponent: GetStaticComponent
  ) { }

  ngOnInit() {
    if (!isDevMode()) Mixpanel.trackEvent("View Screen", { "Screen Name": "Login" });
    if (this.session.isActive()) {
      this.router.navigate(["my-invites"], { replaceUrl: true });
    }
    this.createForm();
  }

  //create Form
  createForm() {
    this.form = this.fb.group({
      handle: ["", Validators.compose([Validators.required, Validators.pattern(RegexValidators.email)])],
      password: ["", Validators.required]
    });
  }

  //login
  login(model) {
    this.httpCommonService.post("login", model).subscribe(
      response => {
        const tokenData = { user: model.handle, token: response.token };
        this.session.store("Session", tokenData);
        this.getStaticComponent.getStaticContent();
        this.httpCommonService.get("mydownline").subscribe(response => {
          localStorage.setItem("mydownline", JSON.stringify(response));
        });
        Mixpanel.trackEvent("Login");
        Mixpanel.identifyPerson(response.token);
        if (!response.isLocationSet || (response.profilePicUrl && response.profilePicUrl.slice(0, 6) === "assets")) {
          this.router.navigate(["accounts"], { replaceUrl: true });
          this.notification.showInfo("Please upload your profile pic and add your location.");
        } else if (!response.isLocationSet) {
          this.router.navigate(["accounts"], { replaceUrl: true });
          this.notification.showInfo("Please add your location");
        } else if (!response.profilePicUrl || response.profilePicUrl.slice(0, 6) === "assets") {
          this.router.navigate(["accounts"], { replaceUrl: true });
          this.notification.showInfo("Please upload your profile pic");
        } else {
          let redirectPage = localStorage.getItem("redirectPage");
          if (!redirectPage) redirectPage = "my-invites";
          this.router.navigate([redirectPage], { replaceUrl: true });
        }
      },
      err => {
        if (err.error) {
          this.notification.showError(err.error.reason);
        }
        this.createForm();
      }
    );
  }
}

httpcommon.service.ts

@Injectable()
export class HttpCommonService {
    appUrl: string;
    options: any;
    headers;
    requestOptions;
    constructor(
        private commonServiceProvider: CommonServiceProvider,
        private http: HttpClient) {
        this.appUrl = environment.baseApiUrl;
    }

    //post
    post(url: any, model: any): Observable<any> {
        return this.http.post(this.appUrl + url, model);
    }
}

错误:

Error: Cannot make XHRs from within a fake async test. Request URL: https://mlj0xk2naws.com/latest/static/videos
    at FakeAsyncTestZoneSpec.push../node_modules/zone.js/dist/fake-async-test.js.FakeAsyncTestZoneSpec.onScheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/fake-async-test.js:434:1)
    at ProxyZoneSpec.push../node_modules/zone.js/dist/proxy.js.ProxyZoneSpec.onScheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/proxy.js:144:1)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401:1)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232:1)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:255:1)
    at scheduleMacroTaskWithCurrentZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1114:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:3001:1
    at XMLHttpRequest.proto.(anonymous function) (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1394:1)
    at XMLHttpRequest.send (http://localhost:9876/_karma_webpack_/webpack:/node_modules/raven-js/src/raven.js:1423:1)
    at Observable._subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/common/fesm5/http.js:1639:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:42:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:28:1)
    at DoOperator.push../node_modules/rxjs/_esm5/internal/operators/tap.js.DoOperator.call (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/tap.js:18:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:23:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeTo.js:21:1
    at subscribeToResult (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeToResult.js:6:1)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:70:1)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:67:1)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:50:1)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54:1)
    at Observable._subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/observable/scalar.js:5:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:42:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:28:1)
    at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:28:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:23:1)
    at FilterOperator.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/filter.js:15:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:23:1)
    at GetStaticComponent../src/app/services/static-video/get-static-component.service.ts.GetStaticComponent.getStaticContent (http://localhost:9876/_karma_webpack_/webpack:/src/app/services/static-video/get-static-component.service.ts:26:18)
    at SafeSubscriber._next (http://localhost:9876/_karma_webpack_/webpack:/src/app/login/login.component.ts:48:33)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:195:1)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:133:1)
    at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:77:1)
    at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54:1)
    at Observable._subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/observable/scalar.js:5:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:42:1)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (http://localhost:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:28:1)
    at LoginComponent../src/app/login/login.component.ts.LoginComponent.login (http://localhost:9876/_karma_webpack_/webpack:/src/app/login/login.component.ts:44:49)
    at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/login/login.component.spec.ts:207:19)
    at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/fake-async-test.js:593:1)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:388:1)
    at ProxyZoneSpec.push../node_modules/zone.js/dist/proxy.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/proxy.js:128:1)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:387:1)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:138:1)
    at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/jasmine-patch.js:145:1)
    at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/jasmine-patch.js:160:1)
    at attemptSync (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?da99c5b057693d025fad3d7685e1590600ca376d:3898:24)
    at ZoneQueueRunner.QueueRunner.run (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?da99c5b057693d025fad3d7685e1590600ca376d:3887:9)
    at http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?da99c5b057693d025fad3d7685e1590600ca376d:3924:18
    at http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?da99c5b057693d025fad3d7685e1590600ca376d:3848:9
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/async-test.js:218:1

fakeAsyncTest不支持XHR,因为不是time sensitive task,需要用Mock Http比如Angular HttpTestController来测试XHR.或者如果你想测试 real XHR (我认为在大多数情况下你不应该这样做),你需要使用 jasmine done.

这是适合我的解决方案。

 it('a successful login', () => {
        let httpCommonService = fixture.debugElement.injector.get(HttpCommonService);
        let httpCommonResponse = {
            isValid: true
        };
        spyService = spyOn(httpCommonService, 'post').and.callFake(() => {
            return of(httpCommonResponse);
        });
        component.login(mockModel.model);
        expect(spyService).toHaveBeenCalledTimes(1);
    });

fakeAsyncTest不支持XHR,因为它不是时间敏感的任务。

您必须删除 fakeAsynctick()。 tick 正在使用 fakeAsync。

Angular 6+解.

首先,对于 angular 6+,我们必须使用拦截器来处理它。 您需要创建一个实现 HttpIntercepter 的服务,并且只需覆盖 'intercept' 方法,它应该 return 具有您想要的任何值的观察者。

我遇到了同样的错误,我的解决方案是

  @Injectable()
  class TestHttpRequestInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler):
      Observable<HttpEvent<any>> {
          return new Observable<any>(observer => {
              observer.next({} as HttpEvent<any>);
          });
    }
  }

   beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [SharedModule, RouterTestingModule,
            StoreModule.forRoot(fromReducers.reducer))
          ],
          declarations: [],
          providers: [
            LocalStorageService, 
            {
              provide: HTTP_INTERCEPTORS, useClass: TestHttpRequestInterceptor, multi: true
            }
            ],
          schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA]
        })
          .compileComponents();
      }));

希望代码对您有所帮助。

这是我来自 Cannot make XHRs from within a fake async test 的回答(我第一次回答时我将其发布在错误打开的标签中)

如果您使用的是fakeAsync,请添加tick()函数,并尝试在tick函数中增加定时器来测试它是否有效(例如tick(15000) ~ 15s)

reference