Testing Services

When we have a service without dependencies we can just instantiate it without using Spectator. For example:

describe("AuthService", () => {

  it("should ...", () => {
    const authService = new AuthService();
    expect(authService.isLoggedIn()).toBeTruthy();
  });

});

If you want to use Spectator with the above example, you can do the following:

describe("AuthService", () => {
  const spectator = createService<AuthService>(AuthService);

  it("should ...", () => {
    expect(spectator.service.isLoggedIn()).toBeTruthy();
  });

});

When testing a service it’s often the case that we want to mock other services in its DI, as we focus on the service being tested. For example:

@Injectable()
export class DateService {

  isExpired(time) {
    // ...
  }

}

@Injectable()
export class AuthService {

  constructor( private dateService: DateService ) {
  }

  isLoggedIn() {
    if( this.dateService.isExpired('timestamp') ) {
      return false;
    }
    return true;
  }
}

The following example shows how to test the AuthService with Spectator.

import { createService } from "@netbasal/spectator";

describe("AuthService", () => {

  const spectator = createService({
    service: AuthService,
    mocks: [DateService]
  });

  it("should not be logged in", () => {
    let dateService = spectator.get<DateService>(DateService);
    dateService.isExpired.and.returnValue(true);
    expect(spectator.service.isLoggedIn()).toBeFalsy();
  });

  it("should be logged in", () => {
    let dateService = spectator.get<DateService>(DateService);
    dateService.isExpired.and.returnValue(false);
    expect(spectator.service.isLoggedIn()).toBeTruthy();
  });
});

Every service that you pass to the mocks property will be called with the mockProvider() function.

The mockProvider() function converts each service method to a jasmine spy. (i.e jasmine.createSpy()).

Here are some of the methods it exposes:

    dateService.isExpired.and.callThrough();
    dateService.isExpired.and.callFake(() => fake);
    dateService.isExpired.and.throwError('Error');
    dateService.isExpired.andCallFake(() => fake);

The createService() function returns a plain object with the following properties:

  • service - Get an instance of the service
  • get<T> - A proxy for Angular TestBed.get()

If you want to use the actual providers you can still pass the providers key. For example:

  const spectator = createService({
    service: AuthService,
    providers: [DateService]
  });

  it("should be logged in", () => {
    expect(spectator.service.isLoggedIn()).toBeTruthy();
  });

Note: You will still get an autocomplete for these services as spy objects (we're working to solve that).

Typed Mocks

You can use the mockProvider() function with any test, for example:

import { SpyObject, mockProvider } from '@netbasal/spectator';

 let otherService: SpyObject<OtherService>;
 let service: TestedService;

 beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        TestedService,
        mockProvider(OtherService)
      ],
    });

    otherService = TestBed.get(OtherService);
    service = TestBed.get(GoogleBooksService);
  });

  it('should be 0', () => {
    otherService.method.andReturn('mocked value'); // mock is strongly typed

   // then test serivce
  });

results matching ""

    No results matching ""