首页 > 解决方案 > 在 ngOnInit - Angular 11 中订阅的测试组件

问题描述

我是在 Jasmine 和 Karma 中进行测试的新手,我正在尝试弄清楚如何测试在 ngOnInit 中设置的组件的 observable。

我有以下组件:

export class Component implements OnInit{
    
    currentConfig$: Observable<Config>;
    
    constructor(
         private someService: someService,
         private route: ActivatedRoute
    ){}

    ngOnInit() {
        this.route.params.subscribe(params => {
            this.someService.init(params.name)
        })
        this.currentConfig = this.someService.config$
    }

}

这是服务:

export class SomeService {

    private subject: Subject<Config> = new Subject()
    
    readonly config$ = subject.asObservable()

    init(name: string): void {
        this.findOne(name).subscribe(res => {
            if (res)
                this.subject.next({name})
        })
        
    }

    findOne(name): Observable<any> {
        return this.http.get('api');
    }

}

然后我可以使用模板中的异步管道订阅 currentConfig observable。我正在尝试测试currentConfig$组件发出的值。

这是我的测试现在的样子:

fit('should show create component', fakeAsync(() => {
    const component = fixture.componentInstance;
    const debugElement = fixture.debugElement;
    const expected = {name: 'ok'}

    // this works
    someService.config$.subscribe(config => console.log(config));
    
    // this doesn't work even if I put it after the detect changes
    // component.currentConfig$.subscribe(config => console.log(config));

    spyOn(someService, 'findOne').and.returnValue(of(expected));
    fixture.detectChanges(); 

}));

currentConfig$如果我尝试订阅该组件,则该组件未定义。可能是因为异步管道消耗了发出的值吗?还是我完全走错了方向?那我怎么能测试它呢?

我仍然对 spyOn 感到很困惑。是否应该监视 ngOnInit 深处的服务功能?

编辑

我想我解决了。我不得不调用component.ngOnInit()而不是调用fixture.detectChanges(),然后订阅可观察组件,然后调用fixture.detectChanges()

这是最终的测试工作:

fit('should get room config given room name', fakeAsync(() => {
    const component = fixture.componentInstance;

    const config: Config= {
        name: 'name',
    };
    // mock service response
    spyOn(roomService, 'findOne').and.returnValue(of(response));
    // call ngOnInit instead. Detect changes keeps observable cold.
    component.ngOnInit();

    component.roomConfig$.subscribe(config => expect(config).toEqual(roomConfig));
    
    // trigger second change detection.
    fixture.detectChanges();

}));

我不确定为什么 detectChanges 保持可观察到的寒冷。如果有人可以清除它?

标签: angularjasminekarma-jasmine

解决方案


在第一次更改检测期间调用 ngOnInit。在您的测试中,您可以尝试手动调用它,component.ngOnInit()或者,如果您想在更像运行时环境中运行它 - 通过调用更改检测本身fixture.detectChanges()


推荐阅读