I have a service with a simple GET method:
export class MyService {
constructor(private http: HttpClient) {}
getUsers() {
const path = 'https://gorest.co.in/public/v2/users'
return this.http.get(path)
}
}
Next I'm injecting it into a component:
export class AppComponent implements OnInit {
users: any[]
constructor(private _myService: MyService) {}
ngOnInit() {
this._myService.getUsers().subscribe((usersRes) => {
this.users = usersRes
})
}
}
I Also have a simple stub for users:
const usersMock = [
{
gender: 'female',
id: 3971,
name: 'Piotreczi Krawaczi',
},
]
const myServiceStub = jest.fn().mockImplementation(() => ({
getUsers: jest.fn().mockReturnValue(of(usersMock))
})
...and then I want to use it in TestBed in app.components.spec.ts.
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [AppComponent],
providers: [{ MyService, useValue: myServiceStub }],
}).compileComponents()
fixture = TestBed.createComponent(AppComponent)
component = fixture.componentInstance
}))
...finally I want to test that, users isn't empty:
it('should get Users', fakeAsync(() => {
fixture.detectChanges()
expect(component.users.length).toBeGreaterThan(0)
flush()
}))
I'm getting error: TypeError: Cannot read property 'length' of undefined
, whcich is related to expect(component.todos.length).toBeGreaterThan(0)
. Does anybody know why todos isn't updated and code in getUsers().subscribe
isn't executed?
I tried also useClass
insead useValue
with:
providers: [{ MyServiceService, useClass: MyServiceStubClass }],
and:
class MyServiceStubClass {
getTodos() {
return of(todosMock)
}
getUsers() {
return of(usersMock)
}
}
...but it doesn't work.
CodePudding user response:
I am thinking you may need to have a tick
for the subscribe
to take effect before your expect
.
Try this:
class MyServiceStubClass {
getTodos() {
return of(todosMock)
}
getUsers() {
return of(usersMock)
}
}
providers: [{ MyService, useClass: MyServiceStubClass }],
....
it('should get Users', fakeAsync(() => {
// first fixture.detectChanges() calls ngOnInit
fixture.detectChanges();
// tick should wait for the subscribe to be completed before going to expect
tick();
expect(component.users.length).toBeGreaterThan(0);
flush();
}))
CodePudding user response:
I have the soultion. I had to use:
@Injectable()
class MockMyService extends MyService {
override getUsers() {
return of(usersMock)
}
override getTodos() {
return of(todosMock)
}
}
and in TestBed.configureTestingModule
:
providers: [{provide: MyService, useClass: MockMyService}],