web-dev-qa-db-fra.com

Angular 4 tests unitaires avec jasmine/karma avec http post moqueur

J'ai un service que je veux tester un peu dans jasmine angulaire 4 TypeScript.

Maintenant, la http est en train de faire une post, et elle retourne une identité, cependant .. elle n'envoie rien. 

Je veux juste avoir une bonne couverture de code mais je ne comprends pas comment compléter cette déclaration moqueuse.

voici la méthode pour http post dans mon fichier de service

addSession() {
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        return this.http.post(this.url, JSON.stringify({}), options)
            .map((response: Response) => response.json());

}

Puis le fichier SPEC , que je ne comprends pas vraiment tester, je suppose que je prétends avoir reçu un numéro du service http post, la réponse devrait ressembler à 000000014 

Spec

import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'

describe('TrackerFormService', () => {

    let trackerFormService: TrackerFormService,
        mockHttp;

    beforeEach(() => {
        mockHttp = jasmine.createSpyObj('mockHttp', ['get', 'post', 'put']
        )
        trackerFormService = new TrackerFormService(mockHttp);
    });

    describe('addSession', () => {

        it('add session ', () => {
              // how to test,  what to test?    
              // response , is a number?  how to mock/fake this?

        })

    })

})
7
user6321478

Afin de réaliser ce que vous voulez, la maquette dont vous avez besoin est une fonction simple qui retourne la même chose que ce que POST ferait normalement; Une autre chose est que votre test ne doit pas toucher le serveur pour de vrai, alors vous auriez besoin de quelque chose comme ça (vous pourriez avoir besoin d'ajouter d'autres dépendances):

import { HttpModule } from '@angular/http';
import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'

describe('TrackerFormService', () => {
// Mock the service like this and add all the functions you have in this fashion
let trackerFormService: TrackerFormService,
  mockService = {
    addSession: jasmine.createSpy('addSession').and.returnValue(Observable.of('your session object mock goes here'))
  };

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpModule],
      providers: [{
        provide: TrackerFormService,
        useValue: mockService
      }]
    });
  });

  // Do this trick to inject the service every time, and just use `service` in your tests
  beforeEach(inject([TrackerFormService], (trackerFormService) => {
    service = trackerFormService;
  }));

  describe('addSession', () => {
    it('add session ', () => {
      let fakeResponse = null;

      // Call the service function and subscribe to it to catch the fake response coming from the mock.
      service.addSession().subscribe((value) => {
        // in here value will be whatever you put as returnValue (remember to keep the observable.of())
        fakeResponse = value;
      });

      // expects as in any test.
      expect(fakeResponse).toBeDefined();
      expect(fakeResponse).toBe('your session object mock goes here');
    });
  });
});
6
Sonicd300

Avec Angular 4.3 est venu le service HttpClient qui remplace Http et fournit un moyen plus simple de simuler des requêtes HTTP. C'est bien documenté sur la page officielle: https://angular.io/guide/http

0
TekTimmy

Eh bien, comme vous avez configuré le test/la simulation, vous pouvez simuler le retour de l’appel ultérieur et vérifier que vous obtenez le résultat escompté. Ce faisant, vous testerez que la réponse simulée sera correctement convertie par votre relevé de carte. Avec votre espion, vous pouvez également vérifier comment la méthode post a été appelée. Cela permettra de vérifier si les options correspondent à vos attentes.

Mais à mon avis, c’est une solution plutôt compliquée. Je préférerais éviter les simulacres et les espions en séparant la méthode afin que chaque méthode ne fasse qu'une seule chose. Parce que votre méthode addSession fait actuellement trois choses différentes (mais logiquement dépendantes):

  1. créer des options pour un appel addSession xhr
  2. effectue l'appel
  3. convertir la réponse

Si vous divisez la méthode en trois, vous pouvez facilement tester les méthodes n ° 1 et n ° 3 dans des tests séparés et la méthode n ° 2 ne contiendra que l'appel de la bibliothèque http. Cela vous permet d'obtenir la même valeur de test que ci-dessus sans appeler la bibliothèque http.

Maintenant, qu'en est-il de la méthode n ° 2 ... elle n’a toujours pas été testée et, à mon avis, il n’ya aucune raison de la tester du tout. Parce que vous n'avez pas écrit ce code. Aussi, si vous utilisez le module http angulars, je suis sûr qu’ils ont eux-mêmes de solides tests unitaires.

La réponse de votre service doit déjà faire l’objet d’un test d’intégration supplémentaire. Si vous vous exécutez moins souvent, vérifiez que l’API du service vous retournera quand même ce que vous attendez.

Si vous voulez vraiment qu'une ligne verte apparaisse dans la couverture de votre code, vous pouvez éventuellement utiliser une bibliothèque appelée nock. Nock interceptera tout le trafic xhr généré par votre application. Dans votre fichier de test, vous pouvez mapper les requêtes xhr aux réponses simulées avec l'objet nock.

var scope = nock('http://myapp.iriscouch.com')
                .post('/users', {
                  username: 'pgte',
                  email: '[email protected]'
                })
                .reply(201, {
                  ok: true,
                  id: '123ABC',
                  rev: '946B7D1C'
                });

copié à partir de: https://www.npmjs.com/package/nock

Pour des références et des informations supplémentaires sur les tests en général et sur la quantité de tests à effectuer, je vous recommande de regarder "Budgeting Reality" de Justin Searls

0
Tabueeee