angular - Angular 单元测试模拟重播主题
问题描述
我有一个带有重播主题的服务。
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
在组件测试中模拟我的:
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 来订阅吗?
问题:如何模拟这个?
解决方案
createSpyObj
用于创建方法的间谍。您可以将其用于getUser
.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
方法,你可以在它上面创建 spy:
spyOn(userChanged, 'subscribe')
如果要spyObject
与属性混合,可以使用扩展运算符:
const spyObj = {
... jasmine.createSpyObj('MyObject', ['spyMethod']),
myProperty: true,
};
spyObj.spyMethod();
expect(spyObj.spyMethod).toHaveBeenCalled();
expect(spyObj.myProperty).toBeTrue();
推荐阅读
- gradle - Gradle - 列出子项目的任务
- laravel - 使用 livewire 让我的模态拥有正确的产品
- android - 某些设备/地区的 Android SQLite 异常
- php - 在 Laravel 中使用数字前缀和其他字符串前缀制作代码
- reactjs - componentDidUpdate() 进入无限循环
- visual-studio-code - 如何通过拆分在单个 VSCode 集成终端中启动应用程序的多个实例?
- javascript - 打字稿中的 date.prototype.tojson 覆盖未使用正确的上下文
- php - 在 Sylius 的 ResourceController 中创建自定义操作
- function - 在 Scratch 中将文本转换为大写
- kubernetes - 无法使用新上下文连接到 Kubernetes