0
votes

Comment attendre une demande XHR dans un test angulaire

J'ai un composant avec un bouton. Lorsque le bouton est cliqué, une demande HTTP est faite:

it('', async( async () => {
    fixture.detectChanges();

    appPage.loginButtonEl.click(); // XHR request is initiated here
    fixture.detectChanges();

    await fixture.whenStable();

    // HTTP request is still pending here
}))


5 commentaires

Je pense que votre exemple de code doit être ('', async (async () => {...})) . Le premier async est l'utilitaire async et le second est le mot-clé pour la fonction lambda asynchrone. Sinon, écrire attendre entraînera une erreur de compilation.


Juste, mon mal, j'ai oublié de l'ajouter dans l'exemple, mais ce n'est pas mon problème. Merci d'avoir souligné cela.


Depuis que vous utilisez Jasmine, je suppose que vous faites des tests unitaires, vous ne voudrez donc pas faire un appel en arrière - vous voudriez plutôt se moquer de cela. Je ferais quelque chose comme Spyon (Tokenservice, 'Créer'). Et.ReturnValue (de (/ * Valeur de retour * /)) Pour que cela émet immédiatement et complète, vous permettant de tester rapidement.


@DMCGrandle Je souhaite faire des appels de fin de fin dans mes tests d'intégration.


OK alors, pouvez-vous inclure le code pour TokenService , le composant que vous appelez à partir de ce que vous appelle et le reste de votre fichier de spécifications s'il vous plaît?


3 Réponses :


1
votes

éditer: mon mauvais, j'ai mal compris quelque chose. Mais je pense toujours que vous pouvez le résoudre avec un espion sur le composant où le clic se produit, puis vous vous abonnez simplement à vous-même dans le test à la fonction de service, voir Stackblitz .

Pour votre test, cela signifierait ce qui suit: P>

it('', (done) => {
  fixture.detectChanges();    

  // set up spy for the function that gets called in your click() function
  // and basically replacing it with your own implementation here so you can
  // subscribe to it and wait for completion
  let spy = spyOn(appPage, 'myFunction').and.callFake(() => {
  tokensService.create(appPage.userInCreation)
    .subscribe(data => {
      fixture.detectChanges();

      // more expect statements or whatever you need here

      done();
    });
  });

  appPage.loginButtonEl.click();
});


1 commentaires

Ce serait vraiment une solution. +1



1
votes

Vous pouvez utiliser fakeasync code> au lieu de async () code>. J'ai créé un composant, un intercepteur http_interceptor pour renvoyer la réponse après 1000 ms. Voici le code

noop-interceptacor.ts h2>

p>

import { TestBed, async, ComponentFixture, tick, fakeAsync } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { NoopInterceptor } from './noop-interceptor';
import { By } from '@angular/platform-browser';
describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [
        
        HttpClientModule
      ],
      providers: [{ provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true }],
    }).compileComponents();
  }));
  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
  it('should return response',fakeAsync(()=>{
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.debugElement.componentInstance;
    fixture.detectChanges();
    component.getData();
    tick(1000);
    fixture.detectChanges();
    expect(component.data).toBe('body');
  
  }));
  
  it('should display response',fakeAsync(()=>{
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.debugElement.componentInstance;
    fixture.detectChanges();
    component.getData();
    tick(1000);
    fixture.detectChanges();
    let element = fixture.debugElement.query(By.css('.response')).nativeElement;
    
    expect(element.textContent).toBe('body');
  
  }));
  
});


2 commentaires

Mais vous ne faites pas d'appels de back-end, n'est-ce pas? Je souhaite faire de vraies demandes HTTP.


L'intercepteur ici se moque de l'appel HTTP. Vous pouvez le remplacer par un service réel, donner un délai approprié en coche assez longtemps que le service renvoie les données.



-1
votes

Enveloppez votre test avec FAKEASYNC et ajoutez Cochez () à l'intérieur de votre test. XXX

Référence:
https://angular.io/api/core/testing/tick
https://angular.io/api/core/testing/fakeasync


0 commentaires