Reputation: 1371
I am expecting an array to be undefined in a test of my Angular
app. In order to do that, my test needs to first call a function of my tested component. Within that function, it subscribes to a service's function.
Here is my test class. Including the necessary set up of the service and mock service and the test itself. The test includes commented out lines of what I have already tried.
let service: Service;
const mockService = new MockService();
mockService.getById = of([]);
beforeEach(async(() => {
return TestBed.configureTestingModule({
declarations: [leaving out for now],
imports: [leaving out for now],
providers: [
{
provide: Service,
useValue: mockService
}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(Component);
component = fixture.componentInstance;
service = fixture.debugElement.injector.get(Service);
fixture.detectChanges();
});
describe('describe test', function () {
it('test', function () {
//spyOn(mockService, 'getItemsById');
//spyOn(mockService, 'getItemsById').and.returnValue(of('nothing'));
//spyOn(service, 'getItemsById');
//spyOn(mockService, 'getItemsById').and.callThrough();
//spyOn(service, 'getItemsById').and.callThrough();
//spyOn(service, 'getItemsById').and.returnValue(of('nothing')); syntax error
//spyOn(service, 'getItemsById').and.returnValue({ subscribe: () => {} }); syntax error
//spyOn(mockService, 'getItemsById').and.returnValue({ subscribe: () => {} }); syntax error
component.getList();
expect(component.array).toBeUndefined();
});
});
All of what I attempted still results in the error:
TypeError: Cannot read property 'subscribe' of undefined
and it references the line in my component's function where I subscribe to the service's getItemsById
function
my mock service:
getById: Observable<any>;
constructor() {}
getItemsById(id: number){
return this.getById;
}
my tested component that subscribes to the original service's function:
getList(): Model[]{
let temp: Model[] = [];
for (let item of this.items){
let id = item.id;
this.service.getItemsById(id).subscribe(
singleIdItem => {
temp= temp.concat(singleIdItem);
}
);
}
return temp;
}
I did not include my original service since it is being mocked, please let me know if that is needed. I'm assuming the solution is some form of spyOn
but I have tried everything I have been able to find.
Using Angular 8
Upvotes: 1
Views: 976
Reputation: 1371
In my test, I needed to return the proper value from my service
describe('describe test', function () {
it('test', function () {
spyOn(service, 'getItemsById').and.returnValue(of([{name: 'name', id: 10, otherId: 12, startTime: 'time', endTime: 'time', description: 'desc', insertTime: 'time', insertUser:'user', updateTime: 'time', updateUser: 'user'}]));
component.getList();
expect(component.array.size).toEqual(1);
});
});
The value returned is of type Model[]
as defined in my getList
function in my service.
Upvotes: 0
Reputation: 18869
Try this right before the first beforeEach
:
let service: Service;
const mockService = new MockService();
mockService.getById = of([]);
I am thinking adding mockService.getById = of([]);
in the second beforeEach
(remove it from here now that it is added at the top) is too late (the service without getById
has already been injected in the providers of the configureTestingModule
).
=======================Edit===================
I would use createSpyObj
like so:
let mockService: any;
beforeEach(async(() => {
// can name service (first argument) to anything you want, but I called in service in this scenario. It is internal for you
mockService = jasmine.createSpyObj('service', ['getItemsById']);
TestBed.configureTestingModule({
declarations: [leaving out for now],
imports: [leaving out for now],
providers: [
{
provide: Service,
useValue: mockService
}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should do something', () => {
mockService.getItemsById.and.returnValue(of([]));
component.getList();
// the rest of your assertions.
});
Upvotes: 1