2017-09-26 22 views
5

Mam usługę Chcę testować jednostkę w jaśminie 4 maszynopisu.Testowanie w 4 jednostkach z jaśminem/karmą z kpiną z postów http - jak naprawić

Teraz http robi post, ale zwraca tożsamość, jednak .. nie wysyła niczego.

Chcę po prostu mieć dobry zasięg kodu, ale nie rozumiem, jak zakończyć to kpiące oświadczenie.

tutaj jest metoda HTTP POST w moim pliku usług

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()); 

} 

następnie plik SPEC, które nie dostają tego, co naprawdę testy, przypuszczam, udaje, że otrzymała szereg z powrotem z usług hTTP POST, odpowiedź powinna być coś 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? 

     }) 

    }) 

}) 

Odpowiedz

2

W celu osiągnięcia tego, co chcesz, makiety trzeba to prosta funkcja, która zwraca to samo, co POST zrobiłby normalnie; Inną rzeczą jest twój test nie powinien trafić na serwer za prawdziwe, więc trzeba coś jak to (być może trzeba dodać inne zależności):

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

Wraz z Angularem 4.3 pojawiła się usługa HttpClient, która zastępuje Http i zapewnia łatwiejszy sposób na fałszywe żądania HTTP. Jest dobrze udokumentowane na oficjalnej stronie: https://angular.io/guide/http

+0

ja "Już korzystam z drugiego, a ja pytałem o to, jak konkretnie kpić z tego, co mam. to co mówisz jest ekwiwalentem 1. w rdzeniu .net, lub C# 7, możesz teraz zrobić XYZ, tyle fajnie lub 2. w ES6, teraz jest o wiele lepiej ... –

+0

Jeśli dobrze to zrobię chcesz kpić z metody TrackerFormService.addSession() w teście TrackerFormService, która nie ma sensu z mojej perspektywy, ponieważ chcesz przetestować prawdziwą implementację, a nie próbę. – TekTimmy

+0

zwraca odpowiedź z numeru takiego jak 000000015, więc jestem pewien, że ludzie wyśmiali/sfałszowali proces usług http post. mogę znaleźć przykłady, ale są one tak specyficzne, że staram się wymyślić, jak po prostu udawać/podrabiać mój konkretny test, to czego chcę. Nie twierdzę, że wiem, jak to zrobić, więc zadałem pytanie: –

0

próbka testowa przypadku usługi HTTP żąda

describe('Forgot Password Controller', function() { 
 
    var $controller, 
 
     $httpBackend, 
 
     $q, 
 
     $rootScope, 
 
     $state, 
 
     controller, 
 
     scope, 
 
     accountProvider; 
 

 
    beforeEach(module('app')); 
 
    beforeEach(inject(function (_$injector_, _$controller_, _$rootScope_) { 
 

 
     $controller = _$controller_; 
 
     $rootScope = _$rootScope_; 
 
     $httpBackend = _$injector_.get('$httpBackend'); 
 
     $state = _$injector_.get('$state'); 
 
     $q = _$injector_.get('$q'); 
 
     accountProvider = _$injector_.get('accountProvider'); 
 
     scope = _$rootScope_.$new(); 
 

 
     controller = $controller(app.controllers.forgotPassword, { 
 
      $state: $state, 
 
      accountProvider: accountProvider 
 
     }); 
 
    })); 
 

 
    afterEach(function() { 
 
     $httpBackend.verifyNoOutstandingRequest(); 
 
     $httpBackend.verifyNoOutstandingExpectation(); 
 
    }); 
 

 
    describe('forgot password submission', function() { 
 

 
     it('Can submit a forgot password request successfully', function() { 
 
      $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(200); 
 
      spyOn($state, 'go'); 
 
      controller.form = { emailAddress: '[email protected]' }; 
 

 
      controller.submit(); 
 

 
      expect(controller.submitting).toBe(true); 
 

 
      $httpBackend.flush(); 
 

 
      expect(controller.submitting).toBe(false); 
 
      expect($state.go).toHaveBeenCalledWith('login', { successMessage: 'An email sent to ' + controller.form.emailAddress + ' contains instructions for resetting your password.' }); 
 
     }); 
 

 
     it('Can handle when a user is not found when submitting a forgot password request', function() { 
 
      $httpBackend.expectPOST(app.env.EDGE_SERVICE_PATH + '/events/requestPasswordReset').respond(404); 
 
      spyOn($state, 'go'); 
 
      controller.form = { emailAddress: '[email protected]' }; 
 

 
      controller.submit(); 
 

 
      expect(controller.submitting).toBe(true); 
 
      $httpBackend.flush(); 
 

 
      // We intentionally want to make it appear to the user that the password reset email was sent even when a user 
 
      // does not exist, to help hide info about which users exist in the system 
 
      expect(controller.submitting).toBe(false); 
 
      expect($state.go).toHaveBeenCalledWith('login', { successMessage: 'An email sent to ' + controller.form.emailAddress + ' contains instructions for resetting your password.' }); 
 

 
     }); 
 

 
     it('Can handle unexpected errors from submitting a forgot password request', function() { 
 
      $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(500); 
 

 
      controller.submit(); 
 
      $httpBackend.flush(); 
 

 
      expect(controller.errors.unexpectedError).toBe(true); 
 
     }); 
 

 
     it('Can handle 422 validation errors from submitting a forgot password request', function() { 
 
      var responseData = { 
 
       fieldErrors: { 
 
        username: [{code: 'error'}, {code: 'required', message: 'This is required.'}] 
 
       } 
 
      }; 
 
      $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(422, responseData); 
 

 
      controller.submit(); 
 
      $httpBackend.flush(); 
 

 
      expect(controller.errors.validationErrors).toBe(true); 
 
      expect(controller.errors.fieldErrors).toEqual(responseData.fieldErrors); 
 
     }); 
 

 
     it('Can handle 503 service unavailable from submitting a forgot password request', function() { 
 
      $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(503); 
 

 
      controller.submit(); 
 
      $httpBackend.flush(); 
 

 
      expect(controller.errors.serviceUnavailable).toBe(true); 
 
     }); 
 

 
    }); 
 

 
});

+4

To nie jest rozwiązanie kątowe 4. –

+0

tak, tutaj daję pojęcie o tym, jak pisać przypadki testowe dla odpoczynku apis. – AnilKumar

+0

Jak to pomoże wyśmiewać usługę w Ng? –

0

No tak, jak robił konfigurację testy/drwić Możesz fałszywy zwrot wezwania i sprawdzenie, czy uzyskałeś oczekiwany wynik. W ten sposób sprawdzisz, czy wyśmiewana odpowiedź zostanie poprawnie przekonwertowana na podstawie wyciągu z mapy. Z twoim szpiegiem możesz również sprawdzić, jak została wywołana metoda postu. Spowoduje to sprawdzenie, czy opcje pasują do oczekiwanych.

Ale moim zdaniem to dość skomplikowane rozwiązanie. Wolałbym unikać makiet i szpiegów, dzieląc metodę, więc każda metoda polega tylko na jednej rzeczy. Ponieważ metoda addSession aktualnie robi trzy różne (jeszcze logicznie utrzymaniu) rzeczy:

  1. stworzenia możliwości wywołania addSession XHR
  2. wykonuje połączenia
  3. konwertować odpowiedź

Jeśli złamiesz metodą do trzech możesz w łatwy sposób przetestować metody # 1 i # 3 w osobnych testach, a metoda # 2 będzie zawierać tylko wywołanie biblioteki http. Pozwala to osiągnąć tę samą wartość testu jak powyżej bez wywoływania biblioteki http.

A co z metodą # 2 ... wciąż nie jest testowana i moim zdaniem nie ma powodu, aby ją testować w ogóle. Ponieważ nie napisałeś tego kodu.Również jeśli korzystasz z modułu http angulars, jestem pewny, że same mają solidne testy jednostkowe.

Odpowiedź na twoją usługę powinna już być objęta dodatkowym testem integracyjnym, rzadziej sprawdzać, czy usługa API nadal będzie zwracać to, czego oczekujesz.

Jeśli naprawdę chcesz, aby jedna linia była zielona w zasięgu twojego kodu, możesz opcjonalnie użyć biblioteki o nazwie nock. Nock przechwyci cały ruch xhr, który spowoduje twoja aplikacja. W pliku testowym możesz mapować żądania xhr do wyśmianych odpowiedzi za pomocą obiektu nock.

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

skopiowane z: https://www.npmjs.com/package/nock

odsyłającego oraz dodatkowe informacje na temat badań w ogóle, a ile do testowania Polecam oglądanie "Budżetowanie Reality" Justin Searls