【问题标题】:Testing angular service subscribe/unsubscribe from within a component从组件内测试角度服务订阅/取消订阅
【发布时间】:2019-04-01 16:14:54
【问题描述】:

我有这个页面组件类,它只在加载时调用一个服务,它会在该服务内填充一个数组。在此组件上测试订阅和取消订阅功能的最佳方法是什么?

export class HomeComponent implements OnInit, OnDestroy  {
    private destroySubject$: Subject<void> = new Subject();

    constructor(private accountsService: AccountsService) {}

    ngOnInit(): void {
        this.accountsService.getLoginAndAccountsList$()
        .pipe(takeUntil(this.destroySubject$))
        .subscribe(() => { /* do nothing */ }, (error: Error) => {
            console.error('Unable to get the list of accounts!', error);
        });
    }

    ngOnDestroy(): void {
        this.destroySubject$.next();
    }
}

我现在的测试:

describe('Page Component: Home', () => {
    let component: HomeComponent;
    let fixture: ComponentFixture<HomeComponent>;
    let debugEl: DebugElement;
    let accountsService: AccountsService;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [ HttpClientTestingModule,],
            providers: [ AccountsService ],
            declarations: [ HomeComponent]
        }).compileComponents();
        accountsService = TestBed.get(AccountsService);
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(HomeComponent);
        component = fixture.componentInstance;
        debugEl = fixture.debugElement;
    });

    it('should call the accountService to fetch the logins & accounts upon page load', async(() => {
        spyOn(accountsService, 'getLoginAndAccountsList$');
        fixture.detectChanges();
        expect(accountsService.getLoginAndAccountsList$).toHaveBeenCalled();
    }));

    it('should kill the accountService subscription upon page destruction', async(() => {
        spyOn(accountsService, 'getLoginAndAccountsList$');
        fixture.detectChanges();
        component.ngOnDestroy();
        expect(????).toHaveBeenCalled();
    }));
...

第一个测试现在正在运行,但第二个没有,因为我不确定我需要在那里测试什么。当ngOnDestroy 被调用时,如何测试订阅不再有效?

【问题讨论】:

    标签: angular unit-testing angular-test


    【解决方案1】:

    一般来说,这是一个有效的问题,所以这是我的答案: 您可以通过监视观察者的下一个方法来测试订阅是否不再有效。并验证当 observable 发出新值时不再调用它。

    让我详细说明:

    在你的组件中,你有:

    obs$.pipe(
      takeUntil(destroy$$)
    ).subscribe(handleNewValues)
    

    在规范中你应该有这样的东西:

    // we need to mock the service so that we can control the values emited by the observable
    let newValues = Subjects(); 
    let mockService = { getLoginAndAccountsList$: () => newValues.asObservable() }
    
    TestBed.configureTestingModule({
                imports: [ HttpClientTestingModule,],
                providers: [ {provide: AccountsService, useValue: mockService  }], // this is one way of mocking the service
                declarations: [ HomeComponent]
            }).compileComponents();
    
    // in the test
    const spy = spyOn(comp, 'handleNewValues');
    comp.ngOnDestroy(); // cancels the subscription
    newValues.next('test');
    
    expect(spy).not.toHaveBeenCalled();
    
    

    在您描述的特定用例中,我认为根本不需要使用可观察对象,因为您没有使用可观察对象发出的值。 您的服务可以有一个在 ngOnInit 中调用的填充函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      相关资源
      最近更新 更多