This is an angular unit-testing workshop by Younes from Wishtack and we can keep in touch here:
- ℹ️ wishtack.io
- 📺 marmicode.fr
- 🐦 @yjaaidi
- 💻 github/wishtack
It is made to run on codesandbox.
Click here to open the skeleton on Codesandbox.
Let’s start with a presentational component like <app-sandwich-search>
yarn ng g @wishtack/schematics:scam sandwich-search
xit('🚧 should search and display sandwiches', () => {
throw new Error('🚧 work in progress!');
});
// @todo create the component with…
// @todo check this and that
export class Sandwich {
id: string;
name: string;
price: number;
constructor(args: Partial<Sandwich> = {}) {
this.id = args.id;
this.name = args.name;
this.price = args.price;
}
}
const data$ = of(42)
data$.subscribe(console.log); // 42
… and let’s skip tests for now
yarn ng g service sandwich-search/sandwich-search —skipTests
yarn ng g service cart/cart —skipTests
Top down approach helps with generation and enforces good design. Start with the usage and not the implementation or interface.
class FavoriteColorService {
getFavoriteColor(userId) {
...
}
}
function getCurrentUserFavoriteColor() {
return getFavoriteColor(currentUser.id);
}
it('...', () => {
const favoriteColorService = new FavoriteColorService();
spyOn(favoriteColorService, 'getFavoriteColor').and.returnValue('RED');
expect(getCurrentUserFavoriteColor()); // 'RED'
// ⚠️ remember to check that the spy has been called with the right parameters
expect(favoriteColorService.getFavoriteColor).toHaveBeenCalledWith('FOO'); // FAIL! Was called with `undefined` instead of FOO
});
yarn ng g @wishtack/schematics:scam sandwich-list
fixture.debugElement.queryAll(By.css('…'));
fixture.detectChanges();
<button data-role="destroy-planet-button">DESTROY PLANET</button>
expect(fixture.debugEment.query(By.css('[data="destroy-planet-button"]'))).toBeNull(); // 😰
const clickEvent = {};
fixture.debugElement.query(...).triggerEventHandler('click', clickEvent);
😉 EventEmitter
is a Subject
which is an Observable
, so you can subscribe to the output.
TestBed.configureTestingModule({
declarations: [DestroyPlanetComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
let myService: MyService;
beforeEach(() => myService = TestBed.inject(MyService)); // Since Angular 9
beforeEach(() => myService = TestBed.get(MyService)) // Before Angular 9
🐞 There are some memory limitations on codesandbox that can make karma crash.
If you want to use karma and you don't need to run the app simultaneously, then you can simply replace "start": "ng serve..."
by "start": "ng test"
.
Codesandbox will run karma instead of the app which will reduce memory usage.