Last active
May 15, 2018 22:25
-
-
Save bcabanes/d4654f2cd5d719f5484e4283a78d9e63 to your computer and use it in GitHub Desktop.
Angular component testing - isolated, shallow, integrated
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ComponentFixture, TestBed, async } from '@angular/core/testing'; | |
import { By } from '@angular/platform-browser'; | |
import { NO_ERRORS_SCHEMA } from '@angular/core'; | |
import { RouterTestingModule } from '@angular/router/testing'; | |
import { Router } from '@angular/router'; | |
// app | |
import { CounterComponent } from './counter.component'; | |
import { MenuComponent } from './menu.component'; | |
/** | |
* This component has some logic in it, and a very simple template. | |
* For now, we only want to test the class logic. For doing so, | |
* we will test only the component class without rendering the template. | |
* This test is an Isolated test. | |
*/ | |
describe('CounterComponent (isolated test)', () => { | |
it('should instantiate', () => { | |
const component: CounterComponent = new CounterComponent(); | |
expect(component).toBeDefined(); | |
}); | |
it('should start with a counter at `0`', () => { | |
const component: CounterComponent = new CounterComponent(); | |
expect(component.counter).toEqual(0); | |
}); | |
it('should be able to increment the counter (+1)', () => { | |
const component: CounterComponent = new CounterComponent(); | |
component.counter = 5; | |
component.increment(); | |
component.increment(); | |
expect(component.counter).toEqual(7); | |
}); | |
it('should be able to decrement the counter (-1)', () => { | |
const component: CounterComponent = new CounterComponent(); | |
component.counter = 5; | |
component.decrement(); | |
component.decrement(); | |
expect(component.counter).toEqual(3); | |
}); | |
}); | |
/** | |
* Now that the inner class' logic is tested. | |
* To test if the buttons trigger the right logic, we need to test them. | |
* We need to render the template and trigger some clicks. | |
* Because this component'template contains another component, | |
* and we only want to test the relevant part of the template, we will not | |
* render the child component. | |
* This is a Shallow test. | |
*/ | |
describe('CounterComponent (shallow test)', () => { | |
let component: CounterComponent; | |
let fixture: ComponentFixture<CounterComponent>; | |
beforeEach(async(() => { | |
TestBed.configureTestingModule({ | |
declarations: [CounterComponent], | |
schemas: [NO_ERRORS_SCHEMA] | |
}).compileComponents(); // This is not needed if you are in the CLI context | |
})); | |
beforeEach(() => { | |
fixture = TestBed.createComponent(CounterComponent); | |
component = fixture.componentInstance; | |
fixture.detectChanges(); | |
}); | |
it('should instantiate', () => { | |
expect(component).toBeDefined(); | |
}); | |
it('should increment the counter if increment button is clicked (+1)', () => { | |
const button = fixture.debugElement.nativeElement.querySelector('.button-up'); | |
button.click(); | |
button.click(); | |
expect(component.counter).toEqual(2); | |
}); | |
it('should decrement the counter if decrement button is clicked (-1)', () => { | |
component.counter = 5; // Fake some increment clicks before. | |
const button = fixture.debugElement.nativeElement.querySelector('.button-down'); | |
button.click(); | |
button.click(); | |
expect(component.counter).toEqual(3); | |
}); | |
it('should reset the counter if reset button is clicked (0)', () => { | |
component.counter = 3; // Fake some increment clicks before. | |
const button = fixture.debugElement.nativeElement.querySelector('.button-0'); | |
button.click(); | |
expect(component.counter).toEqual(0); | |
}); | |
}); | |
/** | |
* We could now go deeper and test the whole component with its dependencies, | |
* see if everything is working great. | |
* This is an Integrated test. | |
*/ | |
describe('CounterComponent (integrated test)', () => { | |
let component: CounterComponent; | |
let fixture: ComponentFixture<CounterComponent>; | |
let router: Router; | |
beforeEach(async(() => { | |
TestBed.configureTestingModule({ | |
declarations: [CounterComponent, MenuComponent], | |
imports: [RouterTestingModule] | |
}).compileComponents(); // This is not needed if you are in the CLI context | |
})); | |
beforeEach(() => { | |
fixture = TestBed.createComponent(CounterComponent); | |
component = fixture.componentInstance; | |
router = TestBed.get(Router); | |
spyOn(router, 'navigateByUrl'); | |
fixture.detectChanges(); | |
}); | |
it('should instantiate', () => { | |
expect(component).toBeDefined(); | |
}); | |
it('should trigger the navigation to `/home`', async(() => { | |
const link = fixture.debugElement.nativeElement.querySelector('.home-link'); | |
link.click(); | |
expect(router.navigateByUrl).toHaveBeenCalled(); | |
})); | |
it('should trigger the navigation to `/about`', async(() => { | |
const link = fixture.debugElement.nativeElement.querySelector('.about-link'); | |
link.click(); | |
expect(router.navigateByUrl).toHaveBeenCalled(); | |
})); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component } from '@angular/core'; | |
@Component({ | |
selector: 'app-counter', | |
template: ` | |
<header> | |
<app-menu></app-menu> | |
</header> | |
<main> | |
<div> | |
Counter is at {{counter}}. | |
<a [routerLink]="['/home']" class="home-link">Go home</a> | |
</div> | |
<div> | |
<button (click)="increment()" class="button-up">increment</button> | |
<button (click)="decrement()" class="button-down">decrement</button> | |
<button (click)="reset()" class="button-0">reset</button> | |
</div> | |
</main> | |
` | |
}) | |
export class CounterComponent { | |
public counter: number = 0; | |
constructor() { } | |
public increment() { | |
this.counter++; | |
return this.counter; | |
} | |
public decrement() { | |
this.counter--; | |
return this.counter; | |
} | |
public reset() { | |
this.counter = 0; | |
return this.counter; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment