Componenten testen in hoekig gebruik van jasmijn deel 1

Wat je gaat creëren

Test Driven Development is een programmeermethode die door elke ontwikkelaarsgemeenschap op de planeet is gepredikt en gepromoot. En toch is het een routine die grotendeels wordt verwaarloosd door een ontwikkelaar terwijl hij een nieuw raamwerk leert. Het schrijven van eenheidstests vanaf de eerste dag zal u helpen om betere code te schrijven, bugs met gemak te herkennen en een betere ontwikkelingsworkflow te behouden.

Test-driven ontwikkeling in Angular

Angular, een volwaardig front-end ontwikkelplatform, heeft zijn eigen set tools om te testen. We zullen de volgende hulpmiddelen gebruiken in deze tutorial:

  • Jasmine Framework. Jasmine is een populair gedragsgestuurd testraamwerk voor JavaScript. Met Jasmine kun je tests schrijven die expressiever en rechtlijniger zijn. Hier is een voorbeeld om te beginnen. 
 it ('zou een gedefinieerde component moeten hebben', () => verwacht (component) .toBeDefined (););
  • Karma Test Runner. Karma is een tool waarmee je je applicatie in meerdere browsers kunt testen. Karma heeft plug-ins voor browsers zoals Chrome, Firefox, Safari en vele anderen. Maar ik gebruik liever een headless-browser om te testen. Een headless browser mist een GUI, en op die manier kunt u de testresultaten binnen uw terminal bewaren. In deze zelfstudie configureren we Karma voor gebruik met Chrome en, optioneel, een versie zonder kop van Chrome.
  • Angular Testing Utilities. Hulpprogramma's voor hoektesten bieden u een bibliotheek om een ​​testomgeving voor uw toepassing te maken. Klassen zoals TestBed en ComponentFixtures en helperfuncties zoals async en fakeAsync maken deel uit van de @ Hoekige / kern / testen pakket. Kennismaken met deze hulpprogramma's is nodig als u tests wilt schrijven die laten zien hoe uw componenten omgaan met hun eigen sjabloon, services en andere componenten.

We zullen functionele tests met behulp van de gradenboog in deze zelfstudie niet behandelen. Gradenboog is een populair end-to-end-testraamwerk dat interageert met de gebruikersinterface van de toepassing met behulp van een echte browser. 

In deze zelfstudie maken we ons meer zorgen over het testen van componenten en de logica van de component. We zullen echter een aantal tests schrijven die fundamentele UI-interactie demonstreren met behulp van het Jasmine-raamwerk.

Ons doel

Het doel van deze zelfstudie is om de front-end voor een Pastebin-toepassing te maken in een testgestuurde ontwikkelomgeving. In deze tutorial volgen we de populaire TDD-mantra, die "rood / groen / refactorair" is. We zullen tests schrijven die aanvankelijk mislukken (rood) en vervolgens werken aan onze applicatiecode om ze te laten slagen (groen). We zullen onze code refactoren wanneer het begint te stinken, wat betekent dat het opgeblazen en lelijk wordt.  

We zullen tests schrijven voor componenten, hun sjablonen, services en de Pastebin-klasse. De onderstaande afbeelding illustreert de structuur van onze Pastebin-toepassing. De items die grijs worden weergegeven, worden besproken in het tweede deel van de zelfstudie. 

In het eerste deel van de serie concentreren we ons uitsluitend op het opzetten van de testomgeving en het schrijven van basistests voor componenten. Angular is een op componenten gebaseerd raamwerk; daarom is het een goed idee om enige tijd kennis te maken met schrijftests voor componenten. In het tweede deel van de serie zullen we meer complexe tests schrijven voor componenten, componenten met ingangen, gerouteerde componenten en services. Aan het einde van de serie hebben we een volledig werkende Pastebin-toepassing die er zo uitziet.

Weergave van de Pastebin-componentWeergave van het onderdeel AddPaste
Weergave van het ViewPaste-onderdeel

In deze tutorial leert u hoe u:

  • stel Jasmine en Karma samen
  • een Pastebin-klasse maken die een afzonderlijke pasta vertegenwoordigt
  • maak een kale PastebinService 
  • maak twee componenten, Pastebin en AddPaste
  • schrijf eenheidstests

De volledige code voor de zelfstudie is beschikbaar op Github. 

https://github.com/blizzerand/pastebin-angular

Kloon de repo en kijk gerust naar de code als je in een bepaald stadium van deze tutorial twijfelt. Laten we beginnen!

Jasmine en Karma configureren

De ontwikkelaars van Angular hebben het ons gemakkelijk gemaakt om onze testomgeving in te stellen. Om te beginnen, moeten we Angular eerst installeren. Ik gebruik liever de Angular-CLI. Het is een alles-in-één oplossing die zorgt voor het creëren, genereren, bouwen en testen van uw Angular-project.

ng nieuwe Pastebin

Hier is de directory-structuur gemaakt door Angular-CLI. 

Omdat onze interesses meer gericht zijn op de testaspecten in Angular, moeten we op twee soorten bestanden letten.

karma.conf.js is het configuratiebestand voor de Karma-testrunner en het enige configuratiebestand dat we nodig zullen hebben voor het schrijven van eenheidstests in Angular. Standaard is Chrome de standaard browser-launcher die Karma gebruikt om tests te maken. We zullen een aangepast opstartprogramma maken voor het uitvoeren van de Chrome zonder kop en deze toevoegen aan de browsers rangschikking.

/*karma.conf.js*/ browsers: ['Chrome', 'ChromeNoSandboxHeadless'], customLaunchers: ChromeNoSandboxHeadless: base: 'Chrome', flags: ['--no-sandbox', // Zie https: / /chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md '--headless', '--disable-gpu', // Zonder een debugging-poort op afstand wordt Google Chrome onmiddellijk afgesloten. '--remote-debugging-port = 9222',],,,

Het andere type bestand waar we op moeten letten, is alles dat eindigt .spec.ts. Volgens afspraak worden de tests geschreven in Jasmine specs genoemd. Alle testspecificaties moeten zich binnen de toepassingen bevinden src / app / directory, want daar zoekt Karma naar de testspecificaties. Als u een nieuw onderdeel of een nieuwe service maakt, is het belangrijk dat u uw testspecificaties plaatst in dezelfde map als de code voor het onderdeel of de service zich in de directory bevindt.. 

De ng nieuw commando heeft een gemaakt app.component.spec.ts bestand voor onze app.component.ts. Voel je vrij om het open te maken en de Jasmine-testen in Angular goed te bekijken. Zelfs als de code nergens op slaat, is dat prima. We zullen AppComponent behouden zoals het nu is en het gebruiken om de routes op een later tijdstip in de zelfstudie te hosten. 

De pastebinklasse maken

We hebben een Pastebin-klasse nodig om onze Pastebin in de componenten en tests te modelleren. U kunt er een maken met behulp van de Angular-CLI.

ng genereer klasse Pastebin

Voeg de volgende logica toe aan Pastebin.ts:

exportklasse Pastebin id: number; titel: string; taal: string; plakken: string; constructor (waarden: Object = ) Object.assign (this, values);  export const Languages ​​= ["Ruby", "Java", "JavaScript", "C", "Cpp"]; 

We hebben een Pastebin-klasse gedefinieerd en elke instantie van deze klasse heeft de volgende eigenschappen:

  • ID kaart 
  • titel
  • taal
  • pasta

Maak nog een bestand met de naam pastebin.spec.ts voor de testsuite. 

/ * pastebin.spec.ts * / // importeer de Pastebin class import Pastebin van './pastebin'; beschrijven ('Pastebin', () => it ('zou een instantie van Pastebin moeten maken', () => expect (new Pastebin ()). toBeTruthy (););)

De testsuite begint met een beschrijven block, wat een wereldwijde Jasmine-functie is die twee parameters accepteert. De eerste parameter is de titel van de testsuite en de tweede is de daadwerkelijke implementatie. De specificaties worden gedefinieerd met behulp van een het functie die twee parameters nodig heeft, vergelijkbaar met die van de beschrijven blok. 

Meerdere specificaties (het blokken) kunnen worden genest binnen een testsuite (beschrijven blok). Zorg er echter voor dat de titels van de testsuite zo worden benoemd dat ze eenduidig ​​en leesbaarder zijn omdat ze bedoeld zijn als documentatie voor de lezer.. 

Verwachtingen geïmplementeerd met behulp van de verwachten functie, worden gebruikt door Jasmine om te bepalen of een spec moet passeren of falen. De verwachten functie neemt een parameter die bekend staat als de werkelijke waarde. Het wordt dan geketend met een andere functie die de verwachte waarde neemt. Deze functies worden matcher-functies genoemd en we zullen de matcher-functies gebruiken zoals toBeTruthy ()worden gedefinieerd()zijn(), en toContain () veel in deze tutorial. 

 verwachten (nieuwe Pastebin ()). toBeTruthy ();

Dus met deze code hebben we een nieuw exemplaar van de Pastebin-klasse gemaakt en verwachten dat deze waar is. Laten we nog een specificatie toevoegen om te bevestigen dat het Pastebin-model werkt zoals bedoeld. 

it ('zou waarden moeten accepteren', () => let pastebin = new Pastebin (); pastebin = id: 111, title: "Hello world", taal: "Ruby", plak: 'print' Hallo '',  verwacht (pastebin.id) .toEqual (111); verwacht (pastebin.language) .toEqual ("Ruby"); expect (pastebin.paste) .toEqual ('print' Hello "');); 

We hebben de Pastebin-klasse geïnstantieerd en een paar verwachtingen aan onze testspecificaties toegevoegd. Rennen ng-test om te controleren of alle tests groen zijn.

Een Bare-Bones-service maken

Genereer een service met de onderstaande opdracht.

ng service pastebin genereren

PastebinService host de logica voor het verzenden van HTTP-aanvragen naar de server; we hebben echter geen server-API voor de toepassing die we aan het bouwen zijn. Daarom gaan we de servercommunicatie simuleren met behulp van een module die bekend staat als InMemoryWebApiModule. 

Instellen van Angular-in-Memory-Web-API

Installeren hoekig in-memory-web-API via npm:

npm installeer angular-in-memory-web-api --save

Update AppModule met deze versie.

/ * app.module.ts * / import BrowserModule vanuit '@ angular / platform-browser'; import NgModule uit '@ angular / core'; // Componenten importeren AppComponent van './app.component'; // Service voor Pastebin-import PastebinService van "./pastebin.service"; // Modules die in deze tutorial worden gebruikt, importeren HttpModule van '@ angular / http'; // In memory Web api om een ​​http-serverimport InMemoryWebApiModule te simuleren van 'angular-in-memory-web-api'; import InMemoryDataService van './in-memory-data.service'; @NgModule (aangiften: [AppComponent,], import: [BrowserModule, HttpModule, InMemoryWebApiModule.forRoot (InMemoryDataService),], providers: [PastebinService], bootstrap: [AppComponent]) exportklasse AppModule  

Creëer een InMemoryDataService dat implementeert InMemoryDbService

/*in-memory-data.service.ts*/ import InMemoryDbService van 'angular-in-memory-web-api'; importeer Pastebin van './pastebin'; exportklasse InMemoryDataService implementeert InMemoryDbService createDb () const pastebin: Pastebin [] = [id: 0, title: "Hello world Ruby", taal: "Ruby", plak: 'puts "Hello World"', id : 1, titel: "Hallo wereld C", taal: "C", plak: 'printf ("Hallo wereld");', id: 2, titel: "Hallo wereld CPP", taal: "C ++", plakken: 'cout<<"Hello world";', id: 3, title: "Hello world Javascript", language: "JavaScript", paste: 'console.log("Hello world")' ]; return pastebin;  

Hier, pastebin is een array met voorbeeldpasta's die wordt geretourneerd of bijgewerkt wanneer we een HTTP-actie uitvoeren zoals http.get of http.post.  

/*pastebin.service.ts * / import Injectable van '@ angular / core'; importeer Pastebin van './pastebin'; importeer Http, Headers van '@ angular / http'; importeer 'rxjs / add / operator / toPromise'; Exportklasse @Injectable () PastebinService // Het project gebruikt InMemoryWebApi voor de Server API. // Hier "api / pastebin" simuleert een Server API url private pastebinUrl = "api / pastebin"; private headers = new Headers ('Content-Type': "application / json"); constructor (privé http: Http)  // getPastebin () voert http.get () uit en geeft een belofte terug openbare getPastebin (): Promise return this.http.get (this.pastebinUrl) .toPromise () .then (response => response.json (). data) .catch (this.handleError);  private handleError (error: any): Promise console.error ('Er is een fout opgetreden', fout); return Promise.reject (error.message || error); 

De getPastebin () methode maakt een HTTP.get-aanvraag en retourneert een belofte die is opgelost in een array van Pastebin-objecten die door de server zijn geretourneerd.

Als je een krijgt Geen provider voor HTTP fout tijdens het uitvoeren van een specificatie, moet u de HTTPModule importeren in het betreffende spec-bestand. 

Aan de slag met componenten

Componenten zijn de meest elementaire bouwsteen van een gebruikersinterface in een Angular-toepassing. Een hoekapplicatie is een boom met hoekcomponenten. 
- Hoekige documentatie

Zoals eerder in het gedeelte Overzicht is aangegeven, werken we in deze zelfstudie aan twee onderdelen: PastebinComponent en AddPasteComponent. De Pastebin-component bestaat uit een tabelstructuur met een lijst van alle plakken die van de server zijn opgehaald. De AddPaste-component bevat de logica voor het maken van nieuwe pasta's.   

Het ontwerp en het testen van de Pastebin-component

Ga door en genereer de componenten met behulp van Angular-CLI. 

ng g component --spec = false Pastebin

De --spec = false optie geeft de Angular-CLI opdracht geen spec-bestand te maken. Dit komt omdat we eenheidstests voor componenten vanuit het niets willen schrijven. Maak een pastebin.component.spec.ts bestand in de pastebin-component map.

Hier is de code voor pastebin.component.spec.ts.

invoer TestBed, ComponentFixture, async uit '@ angular / core / testing'; importeer DebugElement uit '@ angular / core'; importeer PastebinComponent van './pastebin.component'; importeer By van '@ angular / platform-browser'; importeer Pastebin, Languages van '... / pastebin'; // Modules gebruikt voor het testen van import HttpModule van '@ angular / http'; beschrijf ('PastebinComponent', () => // Typescript declarations. let comp: PastebinComponent; let fixture: ComponentFixture; let de: DebugElement; laat element: HTMLElement; laat mockPaste: Pastebin []; // beforeEach wordt eenmaal voor elk 'it'-blok in een test gebeld. // Gebruik dit om vóór Component (,) => TestBed.configureTestingModule (verklaringen: [PastebinComponent], // declareren dat de testcomponent importeert: [HttpModule],); fixture = TestBed vóór Each (() => TestBed.configureTestingModule. .createComponent (PastebinComponent); comp = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ('. pastebin')); element = de.nativeElement;); )

Er gebeurt hier veel. Laten we het uit elkaar halen en één stuk tegelijk nemen. Binnen de beschrijven blokkeren, hebben we enkele variabelen verklaard en daarna hebben we een beforeEach functie. beforeEach () is een wereldwijde functie geleverd door Jasmine en, zoals de naam al doet vermoeden, het wordt een keer aangeroepen voor elke specificatie in de beschrijven blok waarin het wordt genoemd. 

TestBed.configureTestingModule (declarations: [PastebinComponent], // declare importeert de testcomponent: [HttpModule],);

TestBed klasse is een onderdeel van de Angular-testhulpprogramma's en het maakt een testmodule die vergelijkbaar is met die van de @NgModule klasse. Verder kun je configureren TestBed de ... gebruiken configureTestingModule methode. U kunt bijvoorbeeld een testomgeving voor uw project maken die de werkelijke Angular-toepassing emuleert, en u kunt vervolgens een component uit uw toepassingsmodule halen en deze opnieuw aan deze testmodule koppelen.. 


armatuur = TestBed.createComponent (PastebinComponent); comp = fixture.componentInstance; de = fixture.debugElement.query (By.css ('div')); element = de.nativeElement;

Uit de hoekige documentatie:

De createComponent methode geeft a terug ComponentFixture, een handvat op de testomgeving rondom het gemaakte onderdeel. De fixture biedt toegang tot de componentinstantie zelf en tot de DebugElement, wat een handvat is voor het DOM-element van de component.

Zoals hierboven vermeld, hebben we een armatuur van de PastebinComponent en vervolgens die fixture gebruikt om een ​​exemplaar van de component te maken. We hebben nu toegang tot de eigenschappen en methoden van de component in onze tests door te bellen comp.property_name. Omdat het armatuur ook toegang biedt tot de debugElement, we kunnen nu de DOM-elementen en -selectoren opvragen. 

Er is een probleem met onze code waaraan we nog niet hebben gedacht. Ons onderdeel heeft een externe sjabloon en een CSS-bestand. Het ophalen en lezen van het bestandssysteem is een asynchrone activiteit, in tegenstelling tot de rest van de code, die allemaal synchroon loopt. 

Angular biedt u een functie genaamd asynchrone () die zorgt voor alle asynchrone dingen. Wat async doet, is bijhouden van alle asynchrone taken die erin zitten, terwijl het de complexiteit van asynchrone uitvoering van ons verbergt. Dus we hebben nu twee functies vóór, een asynchrone beforeEach () en een synchrone beforeEach ().

/ * pastebin.component.spec.ts * / // beforeEach wordt eenmaal voor elk 'it'-blok in een test gebeld. // Gebruik dit om vóór Comp (e) aan het onderdeel, de injectieservices, enz. Te configureren (async (() => // async before wordt gebruikt voor het compileren van externe sjablonen die elke async-activiteit is TestBed.configureTestingModule (declarations: [PastebinComponent], / / verklaren dat de testcomponent wordt geïmporteerd: [HttpModule],) .compileComponents (); // compileer sjabloon en css)); beforeEach (() => // En hier is de synchrone async-functie fixture = TestBed.createComponent (PastebinComponent); comp = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ('. pastebin')); element = de.nativeElement;); 

We hebben nog geen testspecificaties geschreven. Het is echter een goed idee om vooraf een overzicht van de specificaties te maken. De onderstaande afbeelding toont een ruw ontwerp van de Pastebin-component.

We moeten tests schrijven met de volgende verwachtingen.

  • De Pastebin-component zou moeten bestaan.
  • De eigenschap title van de component moet in de sjabloon worden weergegeven.
  • De sjabloon moet een HTML-tabel hebben om de bestaande pasta's weer te geven.
  • pastebinService wordt in de component geïnjecteerd en de methoden zijn toegankelijk.
  • Er mogen geen pasta's worden weergegeven tot OnInit () wordt genoemd.
  • Pasta's worden pas weergegeven nadat de belofte in onze Service is verholpen.

De eerste drie tests zijn eenvoudig te implementeren. 

 it ('should have a Component', () => expect (comp) .toBeTruthy ();); it ('should have a title', () => comp.title = 'Pastebin Application'; fixture.detectChanges (); expect (element.textContent) .toContain (comp.title);) it ('should have have een tabel om de pasta's weer te geven, () => verwacht (element.innerHTML) .toContain ("thead"); expect (element.innerHTML) .toContain ("tbody");) 

In een testomgeving bindt Angular niet automatisch de eigenschappen van de component met de sjabloonelementen. Je moet expliciet bellen fixture.detectChanges () elke keer dat u een componenteigenschap met de sjabloon wilt binden. Als u de test uitvoert, krijgt u een foutmelding omdat we de eigenschap title in ons onderdeel nog niet hebben verklaard.

 title: string = "Pastebin Application";

Vergeet niet om de sjabloon bij te werken met een basistabelstructuur.

titel

ID kaart Titel Taal Code

Wat de rest van de gevallen betreft, moeten we de Pastebinservice en schrijf tests die omgaan met component-service-interactie. Een echte dienst kan bellen naar een externe server en het injecteren in zijn ruwe vorm zal een moeizame en uitdagende taak zijn. 

In plaats daarvan moeten we tests schrijven die erop zijn gericht of het onderdeel zoals verwacht met de service samenwerkt. We zullen specs toevoegen die de bespioneren pastebinService en zijn getPastebin () methode.

Importeer eerst het PastebinService in onze testsuite.

importeer PastebinService van '... /pastebin.service';

Voeg het vervolgens toe aan de providers array binnen TestBed.configureTestingModule ().

TestBed.configureTestingModule (declarations: [CreateSnippetComponent], providers: [PastebinService],);

De onderstaande code creëert een Jasmine-spion die is ontworpen om alle oproepen naar de getPastebin () methode en stuur een belofte terug die onmiddellijk wordt opgelost mockPaste.

// De echte PastebinService wordt geïnjecteerd in de component laat pastebinService = fixture.debugElement.injector.get (PastebinService); mockPaste = [id: 1, titel: "Hallo wereld", taal: "Ruby", plak: "zet 'Hallo'"]; spy = spyOn (pastebinService, 'getPastebin') .and.returnValue (Promise.resolve (mockPaste));

De spion maakt zich geen zorgen over de implementatiedetails van de echte service, maar negeert in plaats daarvan elke oproep naar de echte getPastebin () methode. Bovendien zijn alle externe gesprekken binnen begraven getPastebin () worden genegeerd door onze tests. We zullen losse unit-tests schrijven voor Angular services in het tweede deel van de tutorial.

Voeg de volgende tests toe aan pastebin.component.spec.ts.

 it ('mag de pastebin niet vóór OnInit tonen', () => this.tbody = element.querySelector ("tbody"); // Probeer dit zonder de 'replace (\ s \ s + / g, ")' methode en zie wat er gebeurt verwachten (this.tbody.innerText.replace (/ \ s \ s + / g, ")). toBe (" "," tbody zou leeg moeten zijn "); expect (spy.calls.any ()). toBe (false, "Spy moet nog niet worden genoemd");); it ('zou nog steeds geen pastebin moeten tonen na de geïnitialiseerde component', () => fixture.detectChanges (); // de service getPastebin is async, maar de test is dat niet. expect (this.tbody.innerText.replace (/ \ s \ s + / g, ")) .Bebruik (" ", 'tbody moet nog steeds leeg zijn'); verwacht (spy.calls.any ()). ToBe (true, 'getPastebin should be called');); ('zou de pastebin moeten laten zien nadat getPastebin beloftes heeft opgelost', async () => fixture.detectChanges (); fixture.whenStable (). then (() => fixture.detectChanges (); expect (comp.pastebin). toEqual (jasmine.objectContaining (mockPaste)); verwacht (element.innerText.replace (/ \ s \ s + / g, ")). toContain (mockPaste [0] .title););)

De eerste twee tests zijn synchrone tests. De eerste spec controleert of de innerText van de div element blijft leeg zolang het onderdeel niet is geïnitialiseerd. Het tweede argument voor de matcherfunctie van Jasmine is optioneel en wordt weergegeven als de test mislukt. Dit is handig als u meerdere verwachtingsverklaringen binnen een specificatie hebt.

In de tweede spec wordt de component geïnitialiseerd (omdat fixture.detectChanges () wordt aangeroepen) en van de spion wordt ook verwacht dat deze wordt aangeroepen, maar de sjabloon moet niet worden bijgewerkt. Ook al geeft de spion een opgeloste belofte terug, de mockPaste is nog niet beschikbaar. Het zou niet beschikbaar moeten zijn tenzij de test een asynchrone test is.

De derde test gebruikt een asynchrone () functie eerder besproken om de test uit te voeren in een async testzone. asynchrone () wordt gebruikt om een ​​synchrone test asynchroon te maken. fixture.whenStable () wordt aangeroepen wanneer alle lopende asynchrone activiteiten zijn aangevuld en vervolgens een tweede ronde van fixture.detectChanges () wordt aangeroepen om de DOM bij te werken met de nieuwe waarden. De verwachting in de laatste test zorgt ervoor dat onze DOM wordt bijgewerkt met de mockPaste waarden.

Om de tests te laten slagen, moeten we onze updaten pastebin.component.ts met de volgende code.

/*pastebin.component.ts*/ import Component, OnInit uit '@ angular / core'; importeer Pastebin van '... / pastebin'; importeer PastebinService van '... /pastebin.service'; @Component (selector: 'app-pastebin', templateUrl: './pastebin.component.html', styleUrls: ['./pastebin.component.css']) exportklasse PastebinComponent implementeert OnInit title: string = " Pastebin-toepassing "; pastebin: any = []; constructor (public pastebinServ: PastebinService)  // loadPastebin () wordt aangeroepen op init ngOnInit () this.loadPastebin ();  public loadPastebin () // roept de getPastebin () -methode van de pastebin-service aan en slaat het antwoord op in de 'pastebin'-eigenschap this.pastebinServ.getPastebin (). then (pastebin => this.pastebin = pastebin);  

De sjabloon moet ook worden bijgewerkt.

 

titel

ID kaart Titel Taal Code
Paste.id Paste.title Paste.language Bekijk code

Een nieuwe pasta toevoegen

Genereer een AddPaste-component met Angular-CLI. De onderstaande afbeelding geeft het ontwerp van de AddPaste-component weer.


De logica van de component moet voldoen aan de volgende specificaties.

  • De sjabloon van de component AddPaste moet een knop hebben Maak plak.
  • Klikken op de Maak plak knop moet een modale box met id 'source-modal' weergeven.
  • De klikactie zou ook de componenten moeten bijwerken showModal eigendom aan waar. (showModal is een boolean-eigenschap die true wordt wanneer de modal wordt weergegeven en false als de modal is gesloten.)
  • Druk op de opslaan De knop moet een beroep doen op de Pastebin-service addPaste () methode.
  • Klikken op de dichtbij knop moet de ID 'source-modal' uit de DOM verwijderen en de showModal eigendom aan vals.

We hebben de eerste drie tests voor u uitgewerkt. Kijk of je de tests zelf kunt laten doorzetten. 

beschrijven ('AddPasteComponent', () => laat component: AddPasteComponent; laat fixture: ComponentFixture; let de: DebugElement; laat element: HTMLElement; laat spion: jasmijn. laat pastebinService: PastebinService; beforeEach (async (() => TestBed.configureTestingModule (declarations: [AddPasteComponent], imports: [HttpModule, FormsModule], providers: [PastebinService],) .compileComponents ();)); beforeEach (() => // initialisatie fixture = TestBed.createComponent (AddPasteComponent); pastebinService = fixture.debugElement.injector.get (PastebinService); component = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ( '.add-paste')); element = de.nativeElement; spy = spyOn (pastebinService, 'addPaste'). and.callThrough (); // vraag fixture om veranderingen te detecteren fixture.detectChanges ();); it ('should be created', () => expect (component) .toBeTruthy ();); it ('zou de' create Paste 'knop moeten weergeven, () => // Er moet een create-knop in de template worden verwacht (element.innerText) .toContain ("create Paste");); it ('zou modaal niet moeten weergeven tenzij op de knop wordt geklikt', () => // bronmodel is een id voor modaal. Het moet niet worden weergegeven tenzij op de knop create wordt geklikt (element.innerHTML). not.toContain ("source-modal");) it ("zou de modal moeten weergeven wanneer 'create Paste' wordt aangeklikt", () => let createPasteButton = fixture.debugElement.query (By.css ("button") )); // triggerEventHandler simuleert een klikgebeurtenis op het knoopobject createPasteButton.triggerEventHandler ("click", null); fixture.detectChanges (); expect (element.innerHTML) .toContain ("source-modal"); expect (component .showModal) .toBeTruthy ("showModal moet waar zijn");))

DebugElement.triggerEventHandler () is het enige nieuwe hier. Het wordt gebruikt om een ​​klikgebeurtenis te activeren op het knopelement waarop het wordt aangeroepen. De tweede parameter is het gebeurtenisobject en we hebben het leeg gelaten sinds de component Klik() verwacht er geen. 

Samenvatting

Dat is het voor vandaag. In dit eerste artikel hebben we geleerd:

  • hoe je Jasmine en Karma installeert en configureert
  • hoe basistests voor klassen te schrijven
  • hoe eenheidstests voor componenten worden ontworpen en geschreven
  • hoe een basisdienst te creëren
  • hoe Angular testing utilities in ons project te gebruiken

 In de volgende tutorial zullen we nieuwe componenten maken, meer testcomponenten schrijven met inputs en outputs, services en routes. Blijf op de hoogte voor het tweede deel van de serie. Deel uw mening via de opmerkingen.