Angular Service testing with http and other dependencies

Viewed 116

I have written a wrapper for httpclient which sets the config from the observable and also uses toastr in case of error. It doesn't fail when the other two constructor injections are removed.

In case I mock RestService, I cant use HttpTestingController which provides other useful methods for httpclient testing

rest.service.ts

@Injectable()
export class RestService {
    public baseUrl = null;

    constructor(
        private http: HttpClient,
        private appConfigService: AppConfigService,
        private toast: ToastNotificationService,
    ) {
        this.getConfig();
    }

    get<T>(url, showError = true): Observable<any> {
        return this.http.get<T>(this.baseUrl + url).pipe(
            catchError((error: HttpErrorResponse) => {
                return this.showError(error, showError);
            }),
        );
    }

    private getConfig() {
        this.appConfigService.appConfig$.subscribe(env => {
            this.baseUrl = env.backendUrl + API_PREFIX;
        });
    }

    private showError(error: HttpErrorResponse, showError) {
        let message = Helpers.getErrorMessageFromObject(error);
        if (showError && message) this.toast.showError(message);

        return throwError(error);
    }   
}

rest.service.spec.ts

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { AppConfigService } from './app-config.service';
import { RestService } from './rest.service';
import { ToastNotificationService } from './toast-notification.service';

describe('RestService', () => {
    let service: RestService;
    let httpMock: HttpTestingController;
    const testData = { name: 'Test Data' };

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [
                RestService,
                {
                    provide: AppConfigService,
                    useValue: jasmine.createSpyObj({
                        appConfig$: of(),
                    }),
                },
                {
                    provide: ToastNotificationService,
                    useValue: jasmine.createSpyObj({
                        showError: function () { },
                    }),
                },
            ],
        });

        service = TestBed.get(RestService);
        httpMock = TestBed.get(HttpTestingController);
    });

    afterEach(() => {
        httpMock.verify();
    });

    it('should be created', () => {
        expect(service).toBeTruthy();
    });

    it('should get the data successful', () => {
        service.baseUrl = '';
        const endpoint = '/api/v1/features/1';

        service.get(endpoint).subscribe((data: any) => {
            expect(data).toEqual(testData);
            expect(service.get).toHaveBeenCalled();
            expect(service.get).toHaveBeenCalledWith(endpoint);
        });

        const req = httpMock.expectOne(endpoint);
        expect(req.request.method).toBe('GET');
        req.flush(testData);
    });
});
0 Answers
Related