https://github.com/wishtack/workshop-angular-testing
Angular testing workshop
https://github.com/wishtack/workshop-angular-testing
angular testing workshop
Last synced: over 1 year ago
JSON representation
Angular testing workshop
- Host: GitHub
- URL: https://github.com/wishtack/workshop-angular-testing
- Owner: wishtack
- Created: 2019-09-25T10:31:03.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T10:04:13.000Z (over 3 years ago)
- Last Synced: 2025-01-21T20:23:19.514Z (over 1 year ago)
- Topics: angular, testing, workshop
- Language: HTML
- Homepage:
- Size: 2.71 MB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Angular Testing Workshop
This is an angular unit-testing workshop by [Younes](https://twitter.com/yjaaidi) from [Wishtack](https://wishtack.io) and we can keep in touch here:
- โน๏ธ [wishtack.io](https://wishtack.io)
- ๐บ [marmicode.fr](https://marmicode.fr)
- ๐ฆ [@yjaaidi](https://twitter.com/yjaaidi)
- ๐ป [github/wishtack](https://github.com/wishtack)
It is made to run on codesandbox.
# Workshop guide
## 0. The skeleton
[Click here to open the skeleton on Codesandbox](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/0-skeleton).
## 1. Isolated testing ``
Letโs start with a presentational component like ``
### 1.1. Create the component
```sh
yarn ng g @wishtack/schematics:scam sandwich-search
```
### 1.2. Add empty specs to share intention
```js
xit('๐ง should search and display sandwiches', () => {
throw new Error('๐ง work in progress!');
});
```
### 1.3. Describe the test with comments
```
// @todo create the component withโฆ
// @todo check this and that
```
### 1.4. ๐ It's time for a sandwich ๐
```typescript
export class Sandwich {
id: string;
name: string;
price: number;
constructor(args: Partial = {}) {
this.id = args.id;
this.name = args.name;
this.price = args.price;
}
}
```
### 1.5. Use `of` function to create an observable from synchronous source
```js
const data$ = of(42)
data$.subscribe(console.log); // 42
```
### 1.6. Create the sandwich search & cart service
โฆ and letโs skip tests for now
```sh
yarn ng g service sandwich-search/sandwich-search โskipTests
yarn ng g service cart/cart โskipTests
```
### 1.7. Implement the test and use IDE to generate the methods with the right signature
Top down approach helps with generation and enforces good design.
Start with the usage and not the implementation or interface.
### 1.8. Enable the test by replacing `xit` with `it`... and make it work
๐๐ค [OPEN SOLUTION](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/1-isolated-testing-sandwich-search)
## 2. Isolated testing `` with spies
```js
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
});
```
๐๐ค [OPEN SOLUTION](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/2-isolated-testing-sandwich-search-with-spies)
## 3. Dom testing ``
### 3.1. Create the `` component
```sh
yarn ng g @wishtack/schematics:scam sandwich-list
```
### 3.2. Check that sandwiches are displayed by querying the view
```js
fixture.debugElement.queryAll(By.css('โฆ'));
```
### 3.3. Remember to trigger the change detection when needed
```js
fixture.detectChanges();
```
### 3.4. Use `data-role` attribute to query elements
```html
DESTROY PLANET
```
```js
expect(fixture.debugEment.query(By.css('[data="destroy-planet-button"]'))).toBeNull(); // ๐ฐ
```
๐๐ค [OPEN SOLUTION](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/3-dom-testing-sandwich-list)
## 4. Dom testing events
### 4.1. Trigger a click
```js
const clickEvent = {};
fixture.debugElement.query(...).triggerEventHandler('click', clickEvent);
```
### 4.2. Subscribe to component's output
๐ `EventEmitter` is a `Subject` which is an `Observable`, so you can subscribe to the output.
๐๐ค [OPEN SOLUTION](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/4-dom-testing-sandwich-list-events)
## 5. Shallow testing
### 5.1. Ignore unknown elements
```js
TestBed.configureTestingModule({
declarations: [DestroyPlanetComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
```
### 5.2. Inject services
```js
let myService: MyService;
beforeEach(() => myService = TestBed.inject(MyService)); // Since Angular 9
beforeEach(() => myService = TestBed.get(MyService)) // Before Angular 9
```
๐๐ค [OPEN SOLUTION](https://codesandbox.io/s/github/wishtack/workshop-angular-testing/tree/5-shallow-testing-sandwich-search)
# Known issues with Codesandbox
๐ 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.