From f4a59262f825484db3288c6c89942bb4384f0d2a Mon Sep 17 00:00:00 2001 From: SantiagoDdaR Date: Tue, 25 Jul 2017 01:28:10 -0300 Subject: [PATCH] Adding unit testing --- src/app/app-status/app-state.service.ts | 39 ++++++++++++++++++++ src/app/app.component.html | 43 ++++------------------ src/app/app.component.ts | 15 +------- src/app/app.module.ts | 21 +++++++++-- src/app/employee/employee.component.ts | 23 ++++++++++++ src/app/employee/employees.html | 4 +++ src/app/home/home.component.ts | 23 ++++++++++++ src/app/home/home.html | 39 ++++++++++++++++++++ src/test.ts | 2 +- src/test/home.component.spec.ts | 45 ++++++++++++++++++++++++ src/test/mocks/app-state.service.mock.ts | 38 ++++++++++++++++++++ 11 files changed, 239 insertions(+), 53 deletions(-) create mode 100644 src/app/app-status/app-state.service.ts create mode 100644 src/app/employee/employee.component.ts create mode 100644 src/app/employee/employees.html create mode 100644 src/app/home/home.component.ts create mode 100644 src/app/home/home.html create mode 100644 src/test/home.component.spec.ts create mode 100644 src/test/mocks/app-state.service.mock.ts diff --git a/src/app/app-status/app-state.service.ts b/src/app/app-status/app-state.service.ts new file mode 100644 index 0000000..048f272 --- /dev/null +++ b/src/app/app-status/app-state.service.ts @@ -0,0 +1,39 @@ +import { NextObserver } from 'rxjs/Observer'; +import { Role } from '../role/role'; +import { Employee } from '../employee/employee'; +import { Injectable } from '@angular/core'; + +@Injectable() +export class AppStateService{ + roles: Role[] = new Array( + new Role(1, 'Backend Dev'), + new Role(2, 'Database dev'), + new Role(3, 'Fontend dev') + ); + employees: Employee[] = new Array( + new Employee(1, 'Tato', this.roles[0]), + new Employee(2, 'Nico', this.roles[2]), + new Employee(3, 'Gabi', this.roles[1]), + new Employee(4, 'Mica', this.roles[1]) + ); + + next: number = 5; + + getRoles(): Role[]{ + return this.roles; + } + + getRole(roleId: number): Role{ + return this.roles.filter((role) => role.id === roleId)[0]; + } + + getEmployee(roleId: number): Employee[]{ + return this.employees.filter((employee) => employee.role.id === roleId); + } + + addEmployee(employee: Employee): void{ + employee.id = this.next; + this.next++; + this.employees.push(employee); + } +} \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 84a8eb2..e0c7f6b 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -6,41 +6,12 @@

-

Testing a form

-
-
- - -
-
- Name is required -
-
- Name must be at least 4 characters long. -
-
- Name cannot be more than 24 characters long. -
-
-
-
- - -
-
Power is required
-
-
- -
+ + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c7c4c4e..128d53e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,4 @@ import { Component } from '@angular/core'; -import { Employee } from './employee/employee' -import { Role } from './role/role' @Component({ selector: 'app-root', @@ -8,16 +6,5 @@ import { Role } from './role/role' styleUrls: ['./app.component.css'] }) export class AppComponent { - title = 'Angular 4 Unit Testing App'; - roles = [ - new Role( 1,'SemiSenior Dev'), - new Role( 2,'Senior Dev'), - new Role( 3,'Super Senior Dev') - ]; - - model = new Employee(0, '', null); - - get diagnostic() { - return JSON.stringify(this.model); - } + title: string = 'Angular 4 Unit Testing App'; } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 45b1b97..73449ca 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,21 +1,38 @@ +import { HomeComponent } from './home/home.component'; +import { EmployeeComponent } from './employee/employee.component'; +import { Route, RouterModule, Routes } from '@angular/router'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; +import { AlertModule } from 'ngx-bootstrap/alert'; import { AppComponent } from './app.component'; +import { AppStateService } from './app-status/app-state.service'; + +const routes: Routes = [ + { path: '', pathMatch: 'full', component: HomeComponent }, + { path: 'employee/:role', component: EmployeeComponent } +]; + @NgModule({ declarations: [ - AppComponent + AppComponent, + EmployeeComponent, + HomeComponent ], imports: [ BrowserModule, FormsModule, + RouterModule.forRoot(routes), + AlertModule.forRoot(), BsDropdownModule.forRoot() ], - providers: [], + providers: [ + AppStateService + ], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/employee/employee.component.ts b/src/app/employee/employee.component.ts new file mode 100644 index 0000000..79c86ee --- /dev/null +++ b/src/app/employee/employee.component.ts @@ -0,0 +1,23 @@ +import { Employee } from './employee'; +import { AppStateService } from '../app-status/app-state.service'; +import { ActivatedRoute, Params } from '@angular/router'; +import { Component, OnInit } from '@angular/core'; + +@Component({ + templateUrl: './employees.html' +}) +export class EmployeeComponent implements OnInit{ + constructor(private _route: ActivatedRoute, private _appState: AppStateService){ } + + title: string; + + employees: Employee[]; + + ngOnInit() { + this._route.params.subscribe((params: Params) => { + let roleId = +params['role']; + this.employees = this._appState.getEmployee(roleId); + this.title = `Listado de ${this._appState.getRole(roleId).name}`; + }); + } +} \ No newline at end of file diff --git a/src/app/employee/employees.html b/src/app/employee/employees.html new file mode 100644 index 0000000..085641f --- /dev/null +++ b/src/app/employee/employees.html @@ -0,0 +1,4 @@ +

{{title}}

+
+ {{employee.id}} - {{employee.name}} - {{employee.role.name}} +
\ No newline at end of file diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts new file mode 100644 index 0000000..fbe669c --- /dev/null +++ b/src/app/home/home.component.ts @@ -0,0 +1,23 @@ +import { NgForm } from '@angular/forms/src/directives'; +import { Employee } from '../employee/employee'; +import { Role } from '../role/role'; +import { AppStateService } from '../app-status/app-state.service'; +import { Component } from '@angular/core'; + +@Component({ + templateUrl: 'home.html' +}) +export class HomeComponent{ + constructor(private _state: AppStateService){ } + + roles: Role[] = this._state.getRoles(); + showSuccessMessage: boolean = false + + model = new Employee(0, '', null); + + onSubmit(employeeForm: NgForm) { + this._state.addEmployee(Object.assign({}, this.model)); + employeeForm.resetForm(); + this.showSuccessMessage = true; + } +} \ No newline at end of file diff --git a/src/app/home/home.html b/src/app/home/home.html new file mode 100644 index 0000000..c304275 --- /dev/null +++ b/src/app/home/home.html @@ -0,0 +1,39 @@ +

Testing a form

+ + Well done! You successfully created an Employee + +
+
+ + +
+
+ Name is required +
+
+ Name must be at least 4 characters long. +
+
+ Name cannot be more than 24 characters long. +
+
+
+
+ + +
+
Power is required
+
+
+ +
\ No newline at end of file diff --git a/src/test.ts b/src/test.ts index cd612ee..c84bf4e 100644 --- a/src/test.ts +++ b/src/test.ts @@ -25,7 +25,7 @@ getTestBed().initTestEnvironment( platformBrowserDynamicTesting() ); // Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); +const context = require.context('./test/', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context); // Finally, start Karma to run the tests. diff --git a/src/test/home.component.spec.ts b/src/test/home.component.spec.ts new file mode 100644 index 0000000..1fe4797 --- /dev/null +++ b/src/test/home.component.spec.ts @@ -0,0 +1,45 @@ +import { FormsModule } from '@angular/forms'; +import { AppStateService } from '../app/app-status/app-state.service'; +import { AppStateServiceMock } from './mocks/app-state.service.mock'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; +import { HomeComponent } from '../app/home/home.component'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AlertModule } from 'ngx-bootstrap/alert'; + +describe('Home Component', function() { + let comp: HomeComponent; + let fixture: ComponentFixture; + let de: DebugElement; + let el: HTMLElement; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + AlertModule, + FormsModule + ], + declarations: [ HomeComponent ], + providers: [{provide: AppStateService, useClass: AppStateServiceMock}] + }); + fixture = TestBed.createComponent(HomeComponent); + comp = fixture.componentInstance; + }); + + it('Submit button disabled (form invalid)', function() { + de = fixture.debugElement.query(By.css('button')); + el = de.nativeElement; + //needed on this example + el.setAttribute('disabled', 'disabled') + spyOn(comp, 'onSubmit'); + el.click(); + expect(comp.onSubmit).not.toHaveBeenCalled(); + }); + + it('Submit disabled (form valid)', function() { + de = fixture.debugElement.query(By.css('button')); + el = de.nativeElement; + spyOn(comp, 'onSubmit'); + el.click(); + expect(comp.onSubmit).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/test/mocks/app-state.service.mock.ts b/src/test/mocks/app-state.service.mock.ts new file mode 100644 index 0000000..570c757 --- /dev/null +++ b/src/test/mocks/app-state.service.mock.ts @@ -0,0 +1,38 @@ +import { Role } from '../../app/role/role'; +import { Employee } from '../../app/employee/employee'; +import { Injectable } from '@angular/core'; + +@Injectable() +export class AppStateServiceMock{ + roles: Role[] = new Array( + new Role(1, 'Backend Dev'), + new Role(2, 'Database dev'), + new Role(3, 'Fontend dev') + ); + employees: Employee[] = new Array( + new Employee(1, 'Tato', this.roles[0]), + new Employee(2, 'Nico', this.roles[2]), + new Employee(3, 'Gabi', this.roles[1]), + new Employee(4, 'Mica', this.roles[1]) + ); + + next: number = 5; + + getRoles(): Role[]{ + return this.roles; + } + + getRole(roleId: number): Role{ + return this.roles.filter((role) => role.id === roleId)[0]; + } + + getEmployee(roleId: number): Employee[]{ + return this.employees.filter((employee) => employee.role.id === roleId); + } + + addEmployee(employee: Employee): void{ + employee.id = this.next; + this.next++; + this.employees.push(employee); + } +} \ No newline at end of file