测试可观察订阅内的行为

问题描述 投票:0回答:1

我无法测试调用 API 服务并订阅它的方法的行为。

我的方法的代码看起来像这样:

verify(): void {
  this.state = VerifyState.VERIFYING;
  this.apiService.verify(this.formGroup.get('code').value).subscribe({
    next: () => {
      this.state = VerifyState.SUCCESS;
    },
    error: (err) => {
      if (err.status === 'some_error') {
        this.state = VerifyState.INVALID_OTP;
      }
    },
  });
}

所以基本上在

verify
上,变量状态更改为
VERIFYING
,并且在 API 调用成功后,它应该更改为
SUCCESS
。简单吧?

我的测试看起来像这样...

it('should set state to VERIFYING and then SUCCESS on successful verification', () => {
  const apiService = spectator.inject(ApiService);
  jest.spyOn(apiService, 'verify').mockReturnValue(of(null));

  spectator.component.verify();

  expect(spectator.component.state).toBe(VerifyState.VERIFYING);

  spectator.detectChanges();

  expect(spectator.component.state).toBe(VerifyState.SUCCESS);
});

理论上这应该可行,但我在方法订阅中添加了

console.log
但它没有被记录。有些事情非常不对劲,我不知道是什么。我尝试了多种方法,
fakeAsync
tick
fixture.whenStable
,但没有任何效果。

我尝试了多种提供服务的方式,

mocks: [ApiService],

providers: [{
  provide: ApiService,
  useValue: {
    verify: jest.fn(),
  }
}]

还有其他人。

我错过了一些明显的东西吗??

angular unit-testing jestjs rxjs angular-spectator
1个回答
0
投票

这不会解决您的问题,但执行

VERIFYING
SUCCESS
状态的更好方法是使用
Subject
,因为
of(null);
可以立即发出,我们将没有机会看到它是
VERIFYING

我添加了一些可能有用的评论。

类似这样的:

// Wrap in fakeAsync
it('should set state to VERIFYING and then SUCCESS on successful verification', fakeAsync(() => {
  const apiService = spectator.inject(ApiService);
  const verifySubject = new Subject<VerifyState>();
  // return the observable of the subject. 
  // Change mockReturnValue to mockImplementation to see if
  // it makes a difference.
  jest.spyOn(apiService, 'verify').mockImplementation(() => verifySubject.asObservable());

  spectator.component.verify();
  tick();
  
  // Now it should be verifying since the subject has not emitted.
  expect(spectator.component.state).toBe(VerifyState.VERIFYING);
  
  // Modify the subject
  verifySubject.next(VerifyState.SUCCESS);
  spectator.detectChanges();
  tick();

  expect(spectator.component.state).toBe(VerifyState.SUCCESS);
}));

要调试为什么它没有进入订阅内部,请确保组件中的

const apiService
与组件中的
ApiService
相同。

© www.soinside.com 2019 - 2024. All rights reserved.