# Unit-Test d'un Service

Il serait dommage de ne pas profiter de la [Dependency Injection](https://guide-angular.wishtack.io/angular/dependency-injection) lors de l'implémentation des tests unitaire.

## `TestBed.get` 👍

La méthode statique **`TestBed.get`** permet d'**injecter les services** dans les tests unitaires.

```typescript
describe('PickyWeatherStation', () => {

    it('should give temperature', fakeAsync(() => {

        const weatherStation: PickyWeatherStation = TestBed.get(PickyWeatherStation);

        let temperature;

        weatherStation.getTemperature('Lyon')
            .subscribe(_temperature => temperature = _temperature);

        expect(temperature).toBe(42);

    }));

});
```

{% hint style="success" %}
Pour éviter de récupérer l'instance dans chaque "spec", pensez à utiliser la fonction `beforeEach`!

```typescript
let weatherStation: PickyWeatherStation;
beforeEach(() => weatherStation = TestBed.get(PickyWeatherStation));
```

{% endhint %}

Pensez à définir un "Live Template" dans l'IDE.

![Angular Test Injection Live Template](https://4009647861-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L9vDDYxu6nH7FVBtFFS%2F-LD_HVZtD-AJAf8EIrWG%2F-LD_HfDPvUm98kCcWGL1%2Fangular-inject-live-template.gif?alt=media\&token=b527bb7c-6fa7-40a8-88a2-3d4fdbfc9a3d)

## `inject` 👎

La fonction `inject` *(du module `@angular/core/testing`)* permet également d'injecter des services dans les tests unitaire.

Cette fonction prend deux paramètres :

* **la liste des tokens à injecter** *(généralement liste des classes à injecter),*
* **une fonction de "callback"** qui prend en paramètre **la liste des services injectés** dans le même ordre que la liste de tokens.

{% hint style="danger" %}
Attention à **ne pas confondre la fonction `inject`** du module **`@angular/core/testing`** avec celle du module **`@angular/core`** qui sert à injecter des services dans les factories `factory: () => new MyService(inject(MyDep))` *(Cf.* [*https://github.com/angular/angular/blob/master/packages/examples/core/di/ts/injector\_spec.ts#L70*](https://github.com/angular/angular/blob/master/packages/examples/core/di/ts/injector_spec.ts#L70)*)*.
{% endhint %}

{% tabs %}
{% tab title="picky-weather-station.ts" %}

```typescript
@Injectable({
    providedIn: 'root'
})
class PickyWeatherStation {

    getTemperature(city): Observable<number> {
        return of(42);
    }

}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="picky-weather-station.spec.ts" %}

```typescript
describe('PickyWeatherStation', () => {

    let weatherStation: PickyWeatherStation;

    beforeEach(inject([PickyWeatherStation], _weatherStation => weatherStation = _weatherStation));

    it('should give temperature', fakeAsync(() => {

        let temperature;

        weatherStation.getTemperature('Lyon')
            .subscribe(_temperature => temperature = _temperature);

        expect(temperature).toBe(42);

    }));

});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
La fonction `inject` peut être utilisée **directement autour de la fonction de "spec"** mais il est généralement plus simple d'ajouter un **`beforeEach` pour chaque service** afin d'éviter les problèmes liés à l'ordre des tokens d'injection et le refactoring en général.
{% endhint %}
