An open API service indexing awesome lists of open source software.

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

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.


Codesandbox Angular Testing

# 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.