角单元测试模拟重播主题

角单元测试模拟重播主题

本文介绍了角单元测试模拟重播主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个重放主题的服务.

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

这篇关于角单元测试模拟重播主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 20:18