如果我有如下测试:
it('should return some observable',async(() => { mockBackend.connections.subscribe((mockConnection: MockConnection) => { const responSEOptions = new ResponSEOptions({ body: JSON.stringify(/* some response */) }); mockConnection.mockRespond(new Response(responSEOptions)); }); service.getSomeObservable() .subscribe(result => { expect(result).toBe(/* expected response */); }); }));
解决方法
@estus是正确的,你不需要取消订阅.
TL;博士;
> Observables / Subjects对所有订阅者持有引用,直到完成.
>无法将具有活动引用的对象标记为垃圾收集.基本的JS.
> Http Observables确实完成了当时的订阅,并为GC释放了它们.
>在Observable / Subject被拆除或完成之前,除非您取消订阅,否则不能进行GC订阅.
考虑一下这个简单的Angular TestBed设置:
describe(`DataService`,() => { let service: DataService; let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule],providers: [ DataService,] }); service = TestBed.get(DataService); httpMock = TestBed.get(HttpTestingController); }); it(`should get a response`,() => { service.getData().subscribe(response => { expect(response).toBeTruthy(); }); });
在通过Angular HttpClient发出Http请求的情况下,Observable将完成,并且将为GC发布对Subscribers的引用.对于如上所示的一般Angular Jasmine测试 – 即使你有一个Observable没有完成 – 服务引用的DataService对象每次调用之前都会被重置,而旧的DataService对象将全部丢失引用并标记为GC.一旦发生这种情况,DataService中Observable / Subject引用的任何订阅都将丢失对它们的引用,并且它们也将被GC.
请记住,Observables会发生内存泄漏,因为它们会保留对所有订阅服务器的引用,除非订阅服务器取消订阅.它们将继续具有对它们及其包含函数的有效引用,并且在Subject / Observable被销毁之前不能标记为GC.如果主题继续存在并且您不断添加订阅者(例如同一订阅者的新实例),您将继续向内存中添加一堆旧的未使用的对象.