12. Test EventService

In this section we will fix the now broken spec files missing newly injected dependencies in the components and services under test.

1. Fix broken tests with injected dependencies

  • Add the fake EventService and HttpClient to the EventComponent.

src/app/event/event.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EventComponent } from './event.component';
import { NO_ERRORS_SCHEMA } from '@angular/compiler/src/core';
import { HttpClientModule, HttpClient } from '@angular/common/http';

import { EventService } from '../../services/event.service';

describe('EventComponent', () => {
  let component: EventComponent;
  let fixture: ComponentFixture<EventComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: HttpClient, useValue: null },
        {
          provide: EventService,
          useValue: {
            getAttendees: () => {}
          }
        }
      ],
      declarations: [EventComponent],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EventComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

2. Fix EventService tests

  • Fix missing injected HttpClient in EventService by using Angular's HttpClientTestingModule.

src/app/event/event.service.spec.ts
import { TestBed, inject } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { EventService } from './event.service';

describe('EventService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [EventService]
    });
  });

  it('should be created', inject([EventService], (service: EventService) => {
    expect(service).toBeTruthy();
  }));
});

3. Add a spy to pass in fake attendees to mock the service

  • Add fake service and spy on it.

src/app/event/container/event/event.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EventComponent } from './event.component';
import { NO_ERRORS_SCHEMA } from '@angular/compiler/src/core';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { of } from 'rxjs';

import { EventService } from '../../services/event.service';

describe('EventComponent', () => {
  let component: EventComponent;
  let fixture: ComponentFixture<EventComponent>;
  let service: EventService;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: HttpClient, useValue: null },
        {
          provide: EventService,
          useValue: {
            getAttendees: () => {}
          }
        }
      ],
      declarations: [EventComponent],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EventComponent);
    component = fixture.componentInstance;
    service = TestBed.get(EventService);
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should have a list of attendees set', () => {
    const fakeAttendees = [{ name: 'FAKE_NAME', attending: false, guests: 0 }];

    jest
      .spyOn(service, 'getAttendees')
      .mockImplementation(() => of(fakeAttendees));

    component.ngOnInit();

    component.attendees$.subscribe(attendees => {
      expect(attendees).toEqual(fakeAttendees);
    });
  });
});
Web Link: Link to the demo app running in StackBlitz

Extras and Homework

Add EventService tests

We have no test coverage on our EventService yet. You can read more about how to use Angular's approach to testing HTTP here https://angular.io/guide/http#testing-http-requests.

Steps:

  1. Provide and inject EventService into test.

  2. Make fake attendees array.

  3. Call services getAttendees method and do not forget to subscribe!

  4. Check the path was called.

  5. Verify there are no outstanding requests.

src/app/event/services/event/event.service.spec.ts
import { TestBed, inject } from '@angular/core/testing';
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';

import { Attendee } from '../../../models';
import { EventService } from './event.service';

describe('EventService', () => {
  let httpTestingController: HttpTestingController;
  let eventService: EventService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [EventService]
    });

    eventService = TestBed.get(EventService);
    httpTestingController = TestBed.get(HttpTestingController);
  });

  it('should be created', inject([EventService], (service: EventService) => {
    expect(service).toBeTruthy();
  }));

  it('can test HttpClient.get attendees', () => {
    const testAttendees: Attendee[] = [
      {
        name: 'Test Data',
        attending: true,
        guests: 1
      }
    ];

    eventService.getAttendees().subscribe();

    const req = httpTestingController.expectOne('/api/attendees');

    expect(req.request.method).toEqual('GET');

    req.flush(testAttendees);

    httpTestingController.verify();
  });
});

Last updated