When run the tests i am getting i am getting the "TypeError: this.dashboardService.serviceAgents$.pipe is not a function" error.
import { Component } from '@angular/core';
import { ServiceDashboardService } from '../services/service-dashboard.service';
import { tap } from 'rxjs/operators';
import { ServiceAgent } from '../interfaces/service-agent';
@Component({
selector: 'app-service-dashboard',
templateUrl: './service-dashboard.page.html',
styleUrls: ['./service-dashboard.page.css'],
})
export class ServiceDashboardPage {
serviceAgentSlideOptions: any = {
slidesPerView: 4
};
serviceAgents$ = this.dashboardService.serviceAgents$
.pipe(
tap(serviceAgents => {
this.serviceAgentSlideOptions.slidesPerView = serviceAgents.length < 4 ? serviceAgents.length : 4;
})
);
constructor(private dashboardService: ServiceDashboardService) { }
}
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ServiceDashboardPage } from './service-dashboard.page';
import { ServiceDashboardService } from '../services/service-dashboard.service';
import { ServiceAgent } from '../interfaces/service-agent';
import { of } from 'rxjs';
describe('ServiceDashboardPage', () => {
let component: ServiceDashboardPage;
let fixture: ComponentFixture<ServiceDashboardPage>;
let serviceDashboardServiceSpy: ServiceDashboardService;
beforeEach(async(() => {
serviceDashboardServiceSpy = jasmine.createSpyObj('ServiceDashboardService',
['serviceAgents$']);
TestBed.configureTestingModule({
declarations: [ServiceDashboardPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: ServiceDashboardService, useValue: serviceDashboardServiceSpy }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ServiceDashboardPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', async(() => {
(serviceDashboardServiceSpy.serviceAgents$ as unknown as
jasmine.Spy).and.returnValue(of([] as ServiceAgent[]));
expect(component).toBeTruthy();
}));
});
There are a number of issue with your code as written. As it was pointed out in the comments above, you clearly want an Observable in the service, but the command:
serviceDashboardServiceSpy = jasmine.createSpyObj('ServiceDashboardService', ['serviceAgents$']);
will create serviceAgents$
as a function, and not as an Observable.
But just changing that won't make your code testable, because you will want to change the value that is returned by that Observable and test to see that your component is reacting properly to those changes. For that you will need to refactor your code. The reason for the refactor is because the way you are setting up your Observable in the component by defining it immediately means that it is very hard to change the value and easily test. Simply moving the assignment to ngOnInit()
however, will make this much more easily testable.
Then, you need to move fixture.detectChanges()
out of the beforeEach()
and into the spec itself (the it()
function). The reason for this is because fixture.detectChanges()
will execute ngOnInit()
which we just set up, and we want to more carefully control when that is called.
Finally, you need to set up something to mock your service class - you were trying to use serviceDashboardServiceSpy
object to do so, but in this case I prefer to use a mock class rather than a spy object. The reason for this is because you are defining serviceAgents$
within the real service class as a PROPERTY and not as a function. This makes it a little more tricky to test, and setting up a mock class instead of a spy object in my opinion makes this a little easier.
Taking all these things into account, I set up this StackBlitz to show your tests passing.
I also added a couple of tests to show how changing the value in the service Observable changes the associated value within your component.
Here is the .spec from that StackBlitz:
class MockServiceDashboardService {
get serviceAgents$() {
return of({length: 2});
}
}
describe('ServiceDashboardPage', () => {
let component: ServiceDashboardPage;
let fixture: ComponentFixture<ServiceDashboardPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ServiceDashboardPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: ServiceDashboardService, useClass: MockServiceDashboardService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ServiceDashboardPage);
component = fixture.componentInstance;
});
it('should create', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
it('should have length of 2', () => {
fixture.detectChanges();
expect(component.serviceAgentSlideOptions.slidesPerView).toEqual(2);
});
it('should have a length of 3', () => {
let dService = TestBed.get(ServiceDashboardService);
spyOnProperty(dService, 'serviceAgents$').and.returnValue(of({length: 3}))
fixture.detectChanges();
expect(component.serviceAgentSlideOptions.slidesPerView).toEqual(3);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With