问题描述
我有一个重放主题的服务.
I have a service with a replay subject.
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
:
Now, I want to mock my UserService
in the component test:
1个选项在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个选项角度测试教程)
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
是否应该返回Observable进行订阅?
Shouldn't of
return an Observable to subscribe to?
问题:如何模拟这个?
推荐答案
createSpyObj
用于在方法上创建间谍.您可以将其用于 UserService
的 getUser
方法.
createSpyObj
is used to to create spies on methods. You could use it for getUser
method of UserService
.
userChanged
只是该类的一个属性.您不需要间谍.
userChanged
is just a property of the class. You don't need a spy for it.
您可以做的只是创建一个返回主题的模拟对象:
What you can do is simply create a mock object that returns subject:
const userChanged = new Subject();
providers: [
...
{provide: UserService, useValue: { userChanged }}
],
{userChanged}
等于 {userChanged:userChanged}
然后,在您的 beforeEach
块中,您将发出一个新的用户实例:
Then, in your beforeEach
block you would emit a new user instance:
//...
beforeEach(() => {
const myUser = new User(...)
userChanged.next(myUser)
})
我建议在 beforeEach
块中执行此操作,以避免不同规格之间的副作用.
I recommend to do this in the beforeEach
block to avoid side effects between different specs.
providers: [
...
{provide: UserService, useValue: { userChanged: of({id: 1}) }}
],
另一种方法是使用 of
方法创建可观察的对象,就像在示例中一样.
Another way of doing the same would be simply creating observable using of
method same way you're doing it in your example.
如果您真的想监视 subscribe
方法,则可以对其进行监视:
If you really want to spy on subscribe
method, you can create spy on it:
spyOn(userChanged,'subscribe')
如果要将 spyObject
与属性混合,则可以使用传播运算符:
If you want to mix spyObject
with properties, you can use spread operator:
const spyObj = {
... jasmine.createSpyObj('MyObject', ['spyMethod']),
myProperty: true,
};
spyObj.spyMethod();
expect(spyObj.spyMethod).toHaveBeenCalled();
expect(spyObj.myProperty).toBeTrue();
这篇关于角单元测试模拟重播主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!