2016-06-09 8 views
1

Ich arbeite daran, Tests für meine Dienste in Angular 2 aufzubauen. Das Erstellen der Mock Backends erweist sich als eine echte Testversion. Ich war in der Lage, die Dienste damit zu prüfen, die tatsächlichen HTTP-Anträge erfolgreich zu machen, aber ich möchte diese vom dritten Teil getrennt halten.Testen von HTTP mit Mockbacks

Ich habe durch die beiden wichtigsten Artikel gekämmt ich in der Lage gewesen zu finden (first, second sowie die angular docs.

Wenn ich erfolgreich http-Anfragen machte die tatsächlichen Leistungen Dritter, musste ich nutzen done(); um sicherzustellen, dass der Test auf den Abschluss der Anfrage gewartet hat.Es scheint, dass der Fall hier derselbe ist.Wenn ich ihn nicht verwende, wird der Test auch mit expect(1).toBe(2); erfolgreich sein.Wenn ich es benutze, wird das Warten unterbrochen damit der Anruf beendet wird. Fehler:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Hier ist mein Code:

import { 
    it, 
    inject, 
    describe, 
    beforeEachProviders, 
    expect, 
} from '@angular/core/testing'; 
import { BaseRequestOptions, Response, ResponseOptions, Http } from '@angular/http'; 
import { MockBackend, MockConnection } from '@angular/http/testing'; 

import { AccountService } from './../../source/scripts/services/account.service'; 
import { provide } from '@angular/core'; 

describe('AccountService',() => { 
    // let service; 

    beforeEachProviders(() => [ 
     AccountService, 
     BaseRequestOptions, 
     MockBackend, 
     provide(Http, { 
      deps: [MockBackend, BaseRequestOptions], 
      useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => { 
       return new Http(backend, defaultOptions); 
      }, 
     }), 
    ]); 

    beforeEach(<any>inject([MockBackend], (backend: MockBackend) => { 
     const baseResponse = new Response(new ResponseOptions({ body: 'got response' })); 
     backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse)); 
    })); 

    // We use 'done' for async callbacks (http calls)  
    it('should return mocked response', (done) => { 

     inject([AccountService], (testService: AccountService) => { 
      testService.getUsers().subscribe((res: Response) => { 
       expect(res.text()).toBe('got response'); 
       expect(1).toBe(2); 
       done(); 
      }); 
     }); 
    }); 
}); 

Wie richtig testen ich http Anrufe mit einem mockbackend? Ich vermute, dass entweder die Links, auf die ich oben Bezug genommen habe, veraltet sind, oder sie haben nicht bestätigt, dass der Test tatsächlich getestet wurde, anstatt nur falsche Positive ohne den Async von done(); zu geben.

Antwort

2

Sie waren sehr nah dran. Nur der asynchrone done ist hier nicht geeignet, da inject diesen anonymen Callback ersetzen muss. Also hier ist die feste Version:

it('should return mocked response', inject([AccountService], (testService: AccountService) => { 
    testService.getUsers().subscribe((res: Response) => { 
    expect(res.text()).toBe('got response'); 
    expect(1).toBe(2); 
    }); 
})); 

Ein weiteres Problem fehlt beforeEach Import:

import { 
    it, 
    inject, 
    describe, 
    beforeEach, // <-- this one was missing 
    beforeEachProviders, 
    expect, 
} from '@angular/core/testing'; 

so gibt es einen beforeEach Instanz Jasmin war das nicht erlaubt inject zu verwenden.

+0

Beantwortet vom Blogautor selbst! Wenn ich meine Behauptung so ändere, dass sie dem entspricht, was Sie oben angegeben haben, wird ein anderer Fehler angezeigt. Ich denke, es ist ein Problem mit der Art, wie es analysiert wird? Es passierte, als ich versuchte, den Dienst auch in die 'beforeEach'-Sektion zu injizieren. Die Ablaufverfolgung ist in etwa so: '_instantiateProvider @ C: /sites/Scratch/prototype_ui/config/karma-test-shim.js: 18060: 38 <- webpack: /// ~/@ angular/core/src/di /reflective_injector.js: 626: 0'. Irgendwelche Ideen? – Aarmora

+0

Ok, es gibt auch keine "Vorher" -Einträge im Import. Ich werde die Antwort aktualisieren :) –

+0

Hmm, das ist seltsam, du hast Recht. Ich benutze es hier und in all meinen anderen Tests und es hat noch nie etwas darüber gesagt, dass es keine Vorabimporte gibt. – Aarmora