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 serviceget<T>
- A proxy for AngularTestBed.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
});