Although I understand that it's best to test code by consuming it the same way it will be in production and therefore not directly dealing with private properties and methods, TypeScript is causing me some confusion.
I have a user service.
// user.service.ts
import {Injectable} from '@angular/core';
import {AppHttpService} from '../app-http/app-http.service'
@Injectable()
export class UserService {
constructor(private appHttp: AppHttpService) {
}
}
As shown, it depends on an appHttp service which has private properties and methods. Let's say it looks like this:
// app-http.service.ts
@Injectable()
export class AppHttpService {
private apiUrl = 'my domain';
constructor(private http: Http, private authHttp: AuthHttp) {
}
post(body): Observable<any> {
return this.http.post(this.apiUrl, body)
.map((res)=>res)
.catch((err)=>null);
}
}
In order to run an isolated test on my user service, I would like to provide it with a simple mock of my appHttp service. However, if I only mock the public methods and properties of appHttp and provide it to my constructor like this:
// user.service.spec.ts
describe('', () => {
let appHttpMock = {
post: jasmine.createSpy('post')
};
let service = new UserService(appHttpMock);
beforeEach(() => {
})
it('', () => {
})
})
I receive an error message stating:
Error:(11, 33) TS2345:Argument of type '{ post: Spy; }' is not assignable to parameter of type 'AppHttpService'. Property 'apiUrl' is missing in type '{ post: Spy; }'.
If I modify my mock to simply add the property, I encounter another error complaining that it's not private. If I create a proper mock class like this:
// app-http.mock.ts
export class AppHttpMockService {
private apiUrl = 'my domain';
constructor() {
}
post() {
}
}
I still face yet another TypeScript error:
Error:(8, 33) TS2345:Argument of type 'AppHttpMockService' is not assignable to parameter of type 'AppHttpService'. Types have separate declarations of a private property 'apiUrl'.
What is a more efficient way to conduct isolated tests (without having to spend time setting up a testbed) without facing issues with TypeScript over the private properties and methods of the mock?