I have an Angular service method that uses another service for making api call. After the call success and inside of the subscription, I call some methods eg notifySucess, emit new value...
My question is how can I test the code block inside the subscription eg expect notifySucess to have been called. I put a break point inside the subscription, but the code execution does not stop there.
For testing component, I know there is 'fixture.detectChanges()' method to be applied. For service testing, are there any similar mechanism?
resource.service.ts
@Injectable({
providedIn: 'root',
})
export class ResourceService {
constructor(
private http: HttpClient,
) {}
putData(newData: Data): Observable<Data> {
return this.http.put<Data>('/api/put-endpoint', newData);
}
}
store.service.ts
@Injectable({
providedIn: 'root',
})
export class StoreService {
constructor(
private resource: ResourceService,
private notificationService: NotificationService,
)
saveChanges(newData: Data) {
this.resourceServie.putData(newData).subscribe(() => {
this.notificationService.notifySuccess('Save changes successfully');
// do something else
}
}
store.service.spec.ts
describe('StoreService', () => {
let storeService: StoreService;
let resourceService: jasmine.SpyObj<ResourceService>;
let notificationService: jasmine.SpyObj<NotificationService>;
notificationService = jasmine.createSpyObj('NotificationService', ['notifySuccess']);
resourceService = jasmine.createSpyObj('ResourceService', ['putData']);
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: ResourceService, useValue: resourceService },
{
provide: NotificationService,
useValue: notificationService,
},
],
});
});
it('should saveChanges', () => {
const newData: Data = {foo: bar};
resourceService.putData.and.returnValue(of(newData));
storeService.putData(newData);
expect(resourceService.putData).toHaveBeenCalledWith(newData); // PASS
expect(notificationService.notifySuccess).toHaveBeenCalledWith(Save changes successfully); // FAIL as the code block inside the subscription does not run
});
})
Your spy need to return some value for triggering subscription. More advanced information about spy you can read here You need to use:
const newData: Data = {foo: bar};
resourceService = spyOn(resourceService,'putData').and.returnValue(newData);
instead of:
resourceService = jasmine.createSpyObj('ResourceService', ['putData']);
You also can see the similar post - Angular - unit test for a subscribe function in a component
Try to implement store.service.spec.ts in this way:
describe('StoreService', () => {
let storeService: StoreService;
let resourceService: ResourceService;
let notificationService: NotificationService;
const newData: Data = {foo: bar};
resourceService = spyOn(resourceService,'putData').and.returnValue(newData);
resourceService = spyOn(notificationService,'notifySuccess').and.returnValue('Save changes successfully');
beforeEach(() => {
TestBed.configureTestingModule({
providers: [],
});
resourceService= TestBed.inject(ResourceService);
notificationService= TestBed.inject(NotificationService);
storeService = TestBed.inject(storeService);
});
it('should saveChanges', () => {
storeService.saveChanges(newData);
expect(resourceService.putData).toHaveBeenCalledWith(newData);
expect(notificationService.notifySuccess).toHaveBeenCalledWith(Save changes successfully); /
});
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.