首页 文章

Angular Jasmine测试没有在ngOnInit中解雇订阅[已解决]

提问于
浏览
1

编辑:我最终解决了这个问题,所以请参考下面的帖子 . 显然,除非我直接在测试中调用 ngOnInit 而不是依赖于 fixture.detectChanges() ,否则观察结果将保持冷态 .

我有一个基本的组件类,在ngOnInit里面它订阅了一个服务调用

ngOnInit() {
    this.activityService.getActivities().subscribe(activities => {
        console.log('inside sub');
        this.recentActivities = activities;
    });
}

所以我包含了这个console.log来查看这个订阅是否曾经执行过 .

在我的测试中,我spyOn这个活动服务方法返回我需要的数据的Observable集合 . 然后在测试中,我执行整个fixture.detectChanges()处理并期望我的数组长度为1 .

fit('should populate recent activities', () => {
    const activities = [new ActivityBuilder()
        .withId('1').withRecentActivityActionId(RecentActivityActionType.Created).build()
    ];
    spyOn(activityService, 'getActivities').and.returnValue(of(activities));

    fixture.detectChanges();
    fixture.whenStable().then(() => {
        fixture.detectChanges();
    });
    fixture.detectChanges();

    expect(component.recentActivities.length).toBe(1);
});

根据Angular文档,他们几乎做了同样的事情,我甚至尝试过fakeAsync方法,但无济于事 . 我在这里想念的是什么?为什么订阅块不执行?

1 回答

  • 1

    经过几个小时的尝试fakeAsync,提供服务的模拟类,各种tick()调用,以及其他几十个帖子和稍微不同的方法,罪魁祸首归结为添加一行: component.ngOnInit(); .

    显然,虽然 fixture.detectChanges() 肯定会调用ngOnInit,但它在某种程度上保持了可观察到的冷漠 . 当我打电话给 fixture.detectChanges() 时,它不会进入observable的订阅 . 一旦我添加 component.ngOnInit() ,observable变得很热,订阅中的代码被执行,我可以看到我的控制台日志被打印 . 奇怪的是,这使得以下 fixture.detectChanges() 调用也会跳转到每个后续调用的订阅代码中 .

    这是我的spec文件的简化版本,希望这可以帮助将来任何人遇到同样的问题 . fakeAsync和同步区域仍然通过测试,我原以为我在fakeAsync区域内至少需要一个tick(),但没有必要 .

    describe('RecentActivityComponent', () => {
    let component: RecentActivityComponent;
    let fixture: ComponentFixture<RecentActivityComponent>;
    let activityService: ActivityService;
    
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [AccordionModule, FontAwesomeModule, HttpClientTestingModule],
            declarations: [ RecentActivityComponent ],
            providers: [AccordionConfig, ActivityService]
        }).compileComponents();
    }));
    
    beforeEach(async () => {
        fixture = TestBed.createComponent(RecentActivityComponent);
        component = fixture.componentInstance;
        activityService = TestBed.get(ActivityService);
    });
    
    it('should populate recent activities', fakeAsync( () => {
        const activities = [new ActivityBuilder()
            .withId('1').withRecentActivityActionId(RecentActivityActionType.Created).build()
        ];
        spyOn(activityService, 'getActivities').and.returnValue(of(activities));
        component.ngOnInit();
        expect(component.recentActivities.length).toBe(1);
    }));
    
    it('should populate recent activities', () => {
        const activities = [new ActivityBuilder()
            .withId('1').withRecentActivityActionId(RecentActivityActionType.Created).build()
        ];
        spyOn(activityService, 'getActivities').and.returnValue(of(activities));
        component.ngOnInit();
        expect(component.recentActivities.length).toBe(1);
    });
    

    });

相关问题