我有一个重放主题的服务。
export class UserService {
public userChanged: ReplaySubject<User> = new ReplaySubject<User>();
...
public getUser(userId?): void {
...
this.http.get(url, httpOptions).pipe(
catchError(this.handleError('getUser', null, 'Couldn\'t get user', options))
).subscribe( (user: User) => {
this.userChanged.next(user);
});
}
我的组件订阅了userChanged
。
this.userService.userChanged.subscribe((user) => {
this.user = user;
});
现在,我想在组件测试中模拟我的UserService
:
1个选项Testing Observables in Angular)
import { of } from 'rxjs';
...
const userServiceSpy = jasmine.createSpyObj('UserService', {'userChanged': of({_id: '1'}) });
或2个选项)
const userServiceSpy = jasmine.createSpyObj('UserService', {'userChanged': () => of({_id: '1'}) });
或3个选项angular test tutorial)
const userServiceSpy = jasmine.createSpyObj('UserService', ['userChanged']});
const userChangedSpy = userServiceSpy.userChanged.and.returnValue( of({_id: '1'}) );
+
TestBed.configureTestingModule({
...
providers: [
...
{provide: UserService, useValue: userServiceSpy}
],
schemas: [NO_ERRORS_SCHEMA]
})
给我这个错误:
this.userService.userChanged.subscribe is not a function
of
是否应返回可观察对象进行订阅?
问题:如何模拟这个?
答案 0 :(得分:2)
createSpyObj
用于在方法上创建间谍。您可以将其用于getUser
的{{1}}方法。
UserService
只是该类的一个属性。您不需要间谍。
您可以做的只是创建一个返回主题的模拟对象:
userChanged
const userChanged = new Subject();
providers: [
...
{provide: UserService, useValue: { userChanged }}
],
等于{ userChanged }
然后,在您的{ userChanged: userChanged }
块中,您将发出一个新的用户实例:
beforeEach
我建议在//...
beforeEach(() => {
const myUser = new User(...)
userChanged.next(myUser)
})
块中执行此操作,以避免不同规格之间的副作用。
beforeEach
执行此操作的另一种方法是使用示例中的 providers: [
...
{provide: UserService, useValue: { userChanged: of({id: 1}) }}
],
方法简单地创建可观察的对象。
如果您真的想监视of
方法,可以对其进行监视:
subscribe
如果要将spyOn(userChanged, 'subscribe')
与属性混合使用,则可以使用扩展运算符:
spyObject
答案 1 :(得分:0)
这可能有点晚了。但是我可以通过以下方法解决此问题:
1. mockUserService = TestBed.get(UserService)
2. By calling the subscribe method using :
mockUserService.userChanged.Subscribe(data => {
// do something
})
注意:第1行和第2行的代码必须位于TestBed.configureTestingModule声明之后的任意位置。