角单元测试模拟重播主题

时间:2019-03-21 11:15:19

标签: 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('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是否应返回可观察对象进行订阅?

问题:如何模拟这个?

2 个答案:

答案 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声明之后的任意位置。