Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度单元测试模拟重放主题_Angular_Unit Testing - Fatal编程技术网

Angular 角度单元测试模拟重放主题

Angular 角度单元测试模拟重放主题,angular,unit-testing,Angular,Unit Testing,我有一个重播主题的服务 export class UserService { public userChanged: ReplaySubject<User> = new ReplaySubject<User>(); ... public getUser(userId?): void { ... this.http.get(url, httpOptions).pipe( catchError(this.handleError('getUse

我有一个重播主题的服务

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);

    });
  }
现在,我想在组件测试中模拟我的
UserService

1个选项)

或2个选项)

或3个选项)

+

给我这个错误:

this.userService.userChanged.subscribe is not a function
不应该返回一个可观察的对象来订阅吗


问题:如何模拟它?

createSpyObj
用于在方法上创建间谍。您可以将其用于
getUser
方法的
UserService

userChanged
只是类的一个属性。你不需要间谍

您只需创建一个返回subject的模拟对象:

const userChanged = new Subject();

 providers: [
    ...
    {provide: UserService, useValue: { userChanged }}
  ],
{userChanged}
等于
{userChanged:userChanged}

然后,在每个
块之前的
中,您将发出一个新的用户实例:

//...
beforeEach(() => {
   const myUser = new User(...)
   userChanged.next(myUser)
})

我建议在每个
之前的
块中执行此操作,以避免不同规格之间的副作用

 providers: [
    ...
    {provide: UserService, useValue: { userChanged: of({id: 1}) }}
  ],

另一种方法是简单地使用
方法的
创建observable,与您在示例中的方法相同


如果您确实想监视
subscribe
方法,您可以在其上创建spy:

spyOn(userChanged,'subscribe')


如果要将
spyObject
与属性混合,可以使用扩展运算符:

const spyObj = {
  ... jasmine.createSpyObj('MyObject', ['spyMethod']),
  myProperty: true,
};

spyObj.spyMethod();

expect(spyObj.spyMethod).toHaveBeenCalled();
expect(spyObj.myProperty).toBeTrue();

这可能有点晚了。。但我通过以下方法解决了这个问题:

1. mockUserService = TestBed.get(UserService)
2. By calling the subscribe method using :
mockUserService.userChanged.Subscribe(data => {
// do something
})

注意:第1行和第2行的代码必须位于TestBed.configureTestingModule声明之后的任何位置。

我必须将.emit更改为。下一步,但它成功了。谢谢如果我想使用此方法和spy on方法,我可以将其组合起来,例如:
{provide:UserService,useValue:{userChanged,userServiceSpy}}
抱歉
.emit
。始终将Subject与EventEmitter-u-)混淆。要将属性与spyObject组合,可以使用spread运算符。检查更新的应答@DDRamone。根据上面的解决方案,您将返回userChanged和observable。当我们在一个服务中编写了多个主题时,您能提供帮助吗?@KarthikBhat您可以根据需要向模拟服务添加任意多个属性。就像在普通对象中一样,只需用逗号分隔它们。如果这不能回答你的问题,请告诉我更多细节,我会尽力帮助你。
const userChanged = new Subject();

 providers: [
    ...
    {provide: UserService, useValue: { userChanged }}
  ],
//...
beforeEach(() => {
   const myUser = new User(...)
   userChanged.next(myUser)
})

 providers: [
    ...
    {provide: UserService, useValue: { userChanged: of({id: 1}) }}
  ],
const spyObj = {
  ... jasmine.createSpyObj('MyObject', ['spyMethod']),
  myProperty: true,
};

spyObj.spyMethod();

expect(spyObj.spyMethod).toHaveBeenCalled();
expect(spyObj.myProperty).toBeTrue();
1. mockUserService = TestBed.get(UserService)
2. By calling the subscribe method using :
mockUserService.userChanged.Subscribe(data => {
// do something
})