Angular4 Services z Testami – czyli nauka Angulara część 2
Angular4 Services to tylko fragment całej aplikacji, więc zakładam w tym miejscu, że masz już stworzony projekt w Angular4. Jeśli jeszcze tego nie zrobiłeś przejdź do części pierwszej: Nauka Angular4 część 1.
Stwórz nowe foldery i pliki w swoim Angularowym projekcie:
W lokalizacji src/app stwórz folder services, a w nim folder person:
src/app:
-services
--person
W folderze src/app/services/person stwórz następujące pliki:
mock-persons.ts
persons.service.spec.ts
person.service.ts
person.ts
Zacznij od edycji ostatniego pliku persons.ts. Plik ten będzie definiował jakie informacje model danych będzie przechowywać o jednej osobie:
export class Person {
id: number;
firstName: string;
lastName: string;
}
Następnie plik mock-persons.ts to zapisana stała PERSONS z listą osób do celów testowych:
import { Person } from './person';
export const PERSONS : Person[] = [
{
id: 123
,firstName : 'Jan'
,lastName : 'Nowak'
}
,{
id: 124
,firstName : 'Maria'
,lastName : 'Nowak'
}
];
Plik person.service.ts zawiera kod Angular4 Service, w moim przypadku service oferuje następujące możliwości:
- dodawania nowych osób,
- usuwanie osób
- edytowanie/aktualizację danych o osobach
- zwracanie listy/tablicy wszystkich osób
- zwracanie objektu konkretnej osoby
- zapisywanie i odczytywanie listy z localStorage
import { Injectable } from '@angular/core';
import { Person } from './person';
import { PERSONS } from './mock-persons';
@Injectable()
export class PersonService {
/**
* Keeps persons array.
*/
persons : Person[] = [];
/**
* Class constructor.
*/
constructor() {
this.loadPersons();
}
/**
* Loads stored persons from local storage.
*/
loadPersons() : void {
this.persons = JSON.parse(localStorage.getItem("persons") || null) || [] ;
}
/**
* Saves persons to local storage.
*/
savePersons(persons : Person[] = this.persons) : void {
localStorage.setItem("persons", JSON.stringify(persons));
}
/**
* Returns Person Object from persons array.
* @param id {number} person's id
* @return {Person}
*/
getPerson(id : number) : Person {
function idEqualsTo(element) {
return element.id === id;
}
return this.persons.find(idEqualsTo);
}
/**
* Updates data about specific person.
* @param id {number} person's id
* @param person {Person} updated person object
*/
editPerson(id : number, person : Person) : void {
function idEqualsTo(element) {
return element.id === id;
}
let index = this.persons.findIndex(idEqualsTo);
if (index > -1) {
this.persons[index] = person;
this.savePersons();
}
}
/**
* Removes Person Object from persons array.
* @param id {number} person's id
*/
removePerson(id : number) : void {
function idEqualsTo(element) {
return element.id === id;
}
let index = this.persons.findIndex(idEqualsTo);
this.persons.splice(index,1);
this.savePersons();
}
/**
* Adds new Person object to persons array, and fires savePersons function.
* @param person {Person}
*/
addPerson(person : Person) : void {
this.persons.push(person);
this.savePersons();
}
/**
* Returns array of person objects.
* @return {Persons[]}
*/
getPersons() : Person[] {
return this.persons;
};
}
Testowanie Angular4 Services
W Angular4/Angular2 testy trzymane są w plikach z kończących się z spec.ts. Plik persons.service.spec.ts zawierać będzie testy jednostkowe (ang. Unit Tests) stworzonego PersonService:
import { TestBed, async, inject } from '@angular/core/testing';
import { PERSONS } from './mock-persons';
import { PersonService } from './person.service';
describe('PersonService', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
PersonService
]
});
}));
it(`should have persons property`, async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
expect(service.persons.length).toBe(2);
});
}));
it('should return proper Person object', async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
expect(service.getPerson(124).firstName).toBe('Maria');
});
}));
it('should save and load persons', async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
service.loadPersons();
expect(service.getPerson(123).firstName).toBe('Jan');
});
}));
it('should edit person', async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
service.editPerson(124,
{
id: 124
,firstName : 'Maria'
,lastName : 'Kowalska'
});
service.loadPersons();
expect(service.getPerson(124).lastName).toBe('Kowalska');
});
}));
it('should remove person', async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
service.removePerson(123);
expect(service.persons.length).toBe(1);
});
}));
it('should add person', async(() => {
inject([PersonService], service => {
service.persons = PERSONS;
service.addPerson({
id: 125
,firstName : 'Jola'
,lastName : 'Nowak'
});
expect(service.persons.length).toBe(3);
});
}));
});
Przykładowe użycie PersonsService w głównym komponencie aplikacji
Plik app.component.ts:
import { Component } from '@angular/core';
import { Person } from './services/person/person';
import { PersonService } from './services/person/person.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [PersonService]
})
export class AppComponent {
persons : Person[];
constructor(private personService: PersonService) {
}
getPersons() : void {
this.persons = this.personService.getPersons();
}
ngOnInit(): void {
this.getPersons();
}
}
Plik widoku app.component.html:
<ul>
<li>{{person.firstName}} {{person.lastName}}</li>
</ul>
Jeśli chcesz przeczytać oficjalną dokumentację na temat Angular Services, to znajdziesz ją tutaj. Jeśli masz jakieś pytania zostaw komentarz. Jeśli pomógł Tobie ten post, to daj lajka poniżej i pomóż innym go odnaleźć. Testowalnego kodu!
Posty do dalszej lektury:
- Nauka Angular4 – Material Design Lite (MDL) – część 3
- TypeScript – Co to jest? TypeScript, a JavaScript?
- Paradygmat MVC Model-View-Controller
- Wybór domeny – Jak wybrać domenę bez błędów?
- 5 trendów technologii frontendowych w 2020
- Szablony WordPress po polsku
- Sztuczna inteligencja, machine learning i Big Data – paliwo XXI wieku