Я застрял при попытке написать тест Jasmine / Karma в приложении Angular 6 для сервиса, который зависит от другого сервиса, и эта зависимость имеет несколько закрытых свойств / методов, которые изменяют выполнение публичного метода, и мой тествсегда терпит неудачу.
Весь код работает должным образом во время выполнения, но я не понимаю, как это правильно проверить. Я пробовал шпионов для закрытых методов и свойств, которые не работают и не меняют их на публичные. Очевидно, я что-то упускаю.
Сейчас мне все равно или я хочу проверить DependencyService
. Я хочу иметь возможность проверить, работает ли MyService
функция doSomething
, в настоящее время она всегда возвращает null
, поэтому мой результат теста равен Failed: Cannot read property 'subscribe' of null
. Удаление оператора if
в postData()
возвращает наблюдаемое, как и ожидалось, и тест проходит успешно.
Мне кажется, что я шпионю за неправильными вещами, поскольку мой тест тесно связан со службой зависимостей или localStorage
значений.
Как мне издеваться / шпионить за checkAuth
и isAuth
в моей служебной зависимости? Возможно, точнее, как правильно проверить doSomething()
, чтобы тест был изолирован для службы MyService
?
export class MyService {
constructor(private depService: DependencyService) { }
public doSomething(additionalPayload: Object) {
const payload = { ...additionalPayload, modified: true };
return this.depService.postData('/api/endpoint', payload);
}
}
export class DependencyService {
constructor(private httpClient: HttpClient) { }
private isAuth: boolean = false;
private checkAuth() {
const token = localStorage.get('token');
if (token !== null) {
this.isAuth = true;
} else {
this.isAuth = false;
}
}
postData(url, body): Observable<any> {
this.checkAuth();
if (!this.isAuth) {
return null;
}
return this.httpClient.post(url, body);
}
}
Пока что myservice.spec.ts
не проходит:
describe('MyService', () => {
let httpTestingController: HttpTestingController;
let myService: MyService;
let dependencyServiceSpy: jasmine.SpyObj<DependencyService>;
beforeEach(() => {
const dependencyServiceSpyObj = jasmine.createSpyObj('DependencyService', ['postData']);
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule ],
providers: [
MyService,
{ provide: DependencyService, useValue: dependencyServiceSpyObj },
]
});
httpTestingController = TestBed.get(HttpTestingController);
myService = TestBed.get(MyService);
dependencyServiceSpy = TestBed.get(DependencyService);
});
afterEach(() => {
httpTestingController.verify();
});
it('#doSomething should post some data', async(() => {
const payloadData: Object = {
name: 'Ash',
food: 'donut'
};
const responseData: Object = {
success: true,
msg: 'Payload received'
};
// HELP HERE ↓
// need to spy/mock dependencyService.isAuth so that it is `true`
// otherwise inside `postData` the if statement will always return a `null` value
// ...spy/mock `localStorage`?
dependencyServiceSpy.postData.and.returnValue(/* return http observable so that .subscribe can be called */);
myService.doSomething(payloadData).subscribe(data => {
expect(data).toEqual(responseData);
}, fail);
const req = httpTestingController.expectOne('/api/endpoint');
expect(req.request.method).toEqual('POST');
expect(req.request.body).toEqual({ ...payloadData, modified: true });
expect(dependencyServiceSpy.postData.calls.count()).toBe(1);
expect(dependencyServiceSpy.postData.calls.mostRecent().returnValue).toBe(responseData);
req.flush(responseData);
}));
});