如何在 Angular 中使用 Jasmine 测试 RxJS switchMap?
Posted
技术标签:
【中文标题】如何在 Angular 中使用 Jasmine 测试 RxJS switchMap?【英文标题】:How to test RxJS switchMap with Jasmine in Angular? 【发布时间】:2022-01-16 11:45:10 【问题描述】:在我的 Angular 项目中,我的一个组件中有这段代码:
delete(post: PostInterface): void
const delete$ = this.appDataService.proxy
.delete(post, this.paginate)
.pipe(switchMap(() => this.loadDatas()));
this.subscriptions.add(
this.appDataService.start(delete$, 'delete').subscribe()
);
在我的规范文件中:
describe('PostListComponent', () =>
let component: PostListComponent;
let fixture: ComponentFixture<PostListComponent>;
let debugElement: DebugElement;
beforeEach(async () =>
await TestBed.configureTestingModule(
// ...
)
.compileComponents()
.then(() =>
fixture = TestBed.createComponent(PostListComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
fixture.detectChanges();
);
);
describe('functions', () =>
it('should be delete with proxy.delete() and reload datas', fakeAsync(() =>
spyOn(component, 'loadDatas');
component.delete(1);
flush();
expect(component.loadDatas).toHaveBeenCalledTimes(1);
));
);
);
在实际环境中switchMap
工作正常,但在测试中失败并显示以下消息:
PostListComponent > functions > should be delete with proxy.delete() and reload datas
Expected spy loadDatas to have been called once. It was called 0 times.
为什么我的测试中没有运行switchMap
?有什么想法吗?
【问题讨论】:
这个答案不能解决你的问题吗? ***.com/questions/49910827/… @S.Hashiba 不,我在提问之前试过了 【参考方案1】:测试没有按预期工作的原因可能在于您没有subscribe
Observable。
订阅启动流,即触发执行嵌入在 Observable 链中的任何代码。
所以,你可能想试试这个版本的测试,看看情况是否有所改善
describe('functions', () =>
it('should be delete with proxy.delete() and reload datas', (done) =>
spyOn(component, 'loadDatas');
component.delete(1).subscribe(
next: err => done(err),
complete: () =>
expect(component.loadDatas).toHaveBeenCalledTimes(1);
done();
);
flush();
);
);
如您所见,我没有使用 fakeAsync
,我假设 delete
实际上已被执行。
【讨论】:
component.delete()
是无效的。不是可观察的。在这个函数中,订阅就在那里。
再次阅读问题后,我看到delete
返回了一个空白。同时我想知道this.appDataService.start(delete$, 'delete').subscribe()
是否真的触发了一些异步逻辑。如果此代码异步执行,则expect
逻辑可能在异步逻辑完成之前执行,因此在loadDatas
执行之前。
是的,但是我该如何解决这个问题?需要重新构建组件代码以使其可测试,还是有其他方法可以以这种形式对其进行测试?
我会将代码移动到外部服务,通过依赖注入传递给组件,因此组件只需要以某种方法订阅或使用async
管道。另一方面,该服务是一个更简单的 Typscript 类,您可以使用我的回复中显示的技术对其进行测试
这听起来像是对代码的重构,而不是 switchMap 问题的解决方案。以上是关于如何在 Angular 中使用 Jasmine 测试 RxJS switchMap?的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 中使用 Jasmine 使用 *ngIf 指令时,如何对元素是不是可见进行单元测试
Jasmine 2.0 async done() 和 angular-mocks inject() 在同一个测试 it()
如何使用 Jasmine 为私有方法编写 Angular / TypeScript 单元测试
如何在 Angular 7 中使用 Karma/Jasmine 为 App_Initializer 编写单元测试用例