jest.js 提供者的 useValue 存根在 angular 中不工作
jest.js and useValue stub for provider not working in angular
我有一个使用简单 GET 方法的服务:
export class MyService {
constructor(private http: HttpClient) {}
getUsers() {
const path = 'https://gorest.co.in/public/v2/users'
return this.http.get(path)
}
}
接下来我将它注入到一个组件中:
export class AppComponent implements OnInit {
users: any[]
constructor(private _myService: MyService) {}
ngOnInit() {
this._myService.getUsers().subscribe((usersRes) => {
this.users = usersRes
})
}
}
我还有一个简单的用户存根:
const usersMock = [
{
gender: 'female',
id: 3971,
name: 'Piotreczi Krawaczi',
},
]
const myServiceStub = jest.fn().mockImplementation(() => ({
getUsers: jest.fn().mockReturnValue(of(usersMock))
})
...然后我想在 app.components.spec.ts.
的 TestBed 中使用它
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [AppComponent],
providers: [{ MyService, useValue: myServiceStub }],
}).compileComponents()
fixture = TestBed.createComponent(AppComponent)
component = fixture.componentInstance
}))
...最后我想测试一下,用户不为空:
it('should get Users', fakeAsync(() => {
fixture.detectChanges()
expect(component.users.length).toBeGreaterThan(0)
flush()
}))
我收到错误:TypeError: Cannot read property 'length' of undefined
,这与 expect(component.todos.length).toBeGreaterThan(0)
有关。有人知道为什么 todos 没有更新并且 getUsers().subscribe
中的代码没有被执行吗?
我也 useClass
insead useValue
尝试过:
providers: [{ MyServiceService, useClass: MyServiceStubClass }],
和:
class MyServiceStubClass {
getTodos() {
return of(todosMock)
}
getUsers() {
return of(usersMock)
}
}
...但它不起作用。
我认为您可能需要 tick
才能使 subscribe
在 expect
之前生效。
试试这个:
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();
}))
我有办法。我必须使用:
@Injectable()
class MockMyService extends MyService {
override getUsers() {
return of(usersMock)
}
override getTodos() {
return of(todosMock)
}
}
并在 TestBed.configureTestingModule
中:
providers: [{provide: MyService, useClass: MockMyService}],
我有一个使用简单 GET 方法的服务:
export class MyService {
constructor(private http: HttpClient) {}
getUsers() {
const path = 'https://gorest.co.in/public/v2/users'
return this.http.get(path)
}
}
接下来我将它注入到一个组件中:
export class AppComponent implements OnInit {
users: any[]
constructor(private _myService: MyService) {}
ngOnInit() {
this._myService.getUsers().subscribe((usersRes) => {
this.users = usersRes
})
}
}
我还有一个简单的用户存根:
const usersMock = [
{
gender: 'female',
id: 3971,
name: 'Piotreczi Krawaczi',
},
]
const myServiceStub = jest.fn().mockImplementation(() => ({
getUsers: jest.fn().mockReturnValue(of(usersMock))
})
...然后我想在 app.components.spec.ts.
的 TestBed 中使用它beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [AppComponent],
providers: [{ MyService, useValue: myServiceStub }],
}).compileComponents()
fixture = TestBed.createComponent(AppComponent)
component = fixture.componentInstance
}))
...最后我想测试一下,用户不为空:
it('should get Users', fakeAsync(() => {
fixture.detectChanges()
expect(component.users.length).toBeGreaterThan(0)
flush()
}))
我收到错误:TypeError: Cannot read property 'length' of undefined
,这与 expect(component.todos.length).toBeGreaterThan(0)
有关。有人知道为什么 todos 没有更新并且 getUsers().subscribe
中的代码没有被执行吗?
我也 useClass
insead useValue
尝试过:
providers: [{ MyServiceService, useClass: MyServiceStubClass }],
和:
class MyServiceStubClass {
getTodos() {
return of(todosMock)
}
getUsers() {
return of(usersMock)
}
}
...但它不起作用。
我认为您可能需要 tick
才能使 subscribe
在 expect
之前生效。
试试这个:
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();
}))
我有办法。我必须使用:
@Injectable()
class MockMyService extends MyService {
override getUsers() {
return of(usersMock)
}
override getTodos() {
return of(todosMock)
}
}
并在 TestBed.configureTestingModule
中:
providers: [{provide: MyService, useClass: MockMyService}],