|
| 1 | +import { Component, EventEmitter, Input, Output } from '@angular/core'; |
| 2 | +import { Location } from '@angular/common'; |
| 3 | +import { render, screen } from '@testing-library/angular'; |
| 4 | +import userEvent from '@testing-library/user-event'; |
| 5 | +import { TestBed } from '@angular/core/testing'; |
| 6 | + |
| 7 | +// with goBackSpy, the implementation of goBack won't be invoked (because it's using the spy) |
| 8 | +test('should call a goBack when user click in the button', async () => { |
| 9 | + const goBackSpy = jest.fn(); |
| 10 | + await render(HeaderBackButtonComponent, { |
| 11 | + declarations: [IconButtonComponent], |
| 12 | + componentProperties: { |
| 13 | + goBack: goBackSpy, |
| 14 | + }, |
| 15 | + }); |
| 16 | + |
| 17 | + const button = screen.getByLabelText(/icon button/i); |
| 18 | + userEvent.click(button); |
| 19 | + expect(goBackSpy).toHaveBeenCalled(); |
| 20 | +}); |
| 21 | + |
| 22 | +// don't spy on goBack, this way the implementation of goBack is invoked, and you can test if location.back() is called |
| 23 | +test('should call a Location.back when user click in the button', async () => { |
| 24 | + await render(HeaderBackButtonComponent, { |
| 25 | + declarations: [IconButtonComponent], |
| 26 | + }); |
| 27 | + |
| 28 | + const location = TestBed.inject(Location); |
| 29 | + jest.spyOn(location, 'back'); |
| 30 | + |
| 31 | + const button = screen.getByLabelText(/icon button/i); |
| 32 | + userEvent.click(button); |
| 33 | + expect(location.back).toHaveBeenCalled(); |
| 34 | +}); |
| 35 | + |
| 36 | +@Component({ |
| 37 | + selector: 'app-cebs-header-back-button', |
| 38 | + template: ` |
| 39 | + <header> |
| 40 | + <app-cebs-icon-button icon="chevron_left" aria-label="back button" (clickEvent)="goBack()"></app-cebs-icon-button> |
| 41 | + </header> |
| 42 | + `, |
| 43 | +}) |
| 44 | +class HeaderBackButtonComponent { |
| 45 | + constructor(private location: Location) {} |
| 46 | + |
| 47 | + goBack(): void { |
| 48 | + this.location.back(); |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +@Component({ |
| 53 | + selector: 'app-cebs-icon-button', |
| 54 | + template: ` |
| 55 | + <button (click)="onClick()" aria-label="icon button"> |
| 56 | + <span class="material-symbols-outlined icon">{{ icon }}</span> |
| 57 | + </button> |
| 58 | + `, |
| 59 | +}) |
| 60 | +class IconButtonComponent { |
| 61 | + @Output() clickEvent = new EventEmitter(); |
| 62 | + @Input() icon!: string; |
| 63 | + |
| 64 | + onClick(): void { |
| 65 | + this.clickEvent.emit(); |
| 66 | + } |
| 67 | +} |
0 commit comments