使用TemplateRefs

时间:2019-05-16 23:10:46

标签: angular unit-testing

我正在尝试使用TemplateRef为Angular组件编写单元测试。这是组件,TypeScript和HTML的全部:

<!-- alerts-display.component.html -->
<ng-template 
    ngFor 
    let-alert 
    [ngForOf]="alerts$ | async" 
    [ngForTemplate]="alertTemplate">
</ng-template>

export class AlertsDisplayComponent implements OnInit {
    public alerts$: Subject<Alert[]>;
    @ContentChild(TemplateRef)
    alertTemplate: TemplateRef<NgForOfContext<Alert>>;
    constructor(private _alertToaster: AlertToasterService) {}

    ngOnInit() {
        this.alerts$ = this._alertToaster.alerts$;
    }
}

基本上,我正在使用异步管道从服务中订阅主题,该服务将为我提供要显示的警报列表,最终开发人员可以传入警报模板(即可以传递引导警报组件) ,或自己的实现)。

我想编写一个单元测试,以确保将警报添加到主题时,元素会输出到页面。到目前为止,这是我的单元测试代码:

@Component({
    selector: 'app-test-host',
    template: `
        <hsa-alerts-display>
            <ng-template let-alert>
                <p>{{ alert.message }}</p>
            </ng-template>
        </hsa-alerts-display>
    `,
})
class TestHostComponent {
    @ViewChild(AlertsDisplayComponent) alertsDisplayComponent: AlertsDisplayComponent;
}

describe('AlertsDisplayComponent', () => {
    let component: TestHostComponent;
    let fixture: ComponentFixture<TestHostComponent>;
    let mockAlertsToasterService: AlertToasterService;

    beforeEach(async(() => {
        mockAlertsToasterService = jasmine.createSpyObj(['toString']);
        mockAlertsToasterService.alerts$ = new Subject<Alert[]>();
        TestBed.configureTestingModule({
            declarations: [AlertsDisplayComponent, TestHostComponent],
            providers: [{ provide: AlertToasterService, useValue: mockAlertsToasterService }],
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(TestHostComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('should show an element for each item in the array list', fakeAsync(() => {
        mockAlertsToasterService.alerts$.next([{ message: 'test message', level: 'success' }]);

        tick();

        const ps = fixture.debugElement.queryAll(By.css('p'));

        expect(ps.length).toBe(1);
    }));
});

我为测试创建了一个测试主机组件,并试图模拟该服务以添加一条消息。然后,我尝试通过p查找fixture元素,但是该测试失败了。它改为0。我尝试了几种不同的方法,但是不确定我是否在正确的轨道上。

任何帮助将不胜感激!

Here's a Stackblitz example as well

1 个答案:

答案 0 :(得分:0)

以上问题中的所有内容都是正确的,我唯一想念的是在上次测试的fixture.detectChanges()之后添加了tick()

完成此操作后,将更新模板并输出p提供的TestHostComponent标记,并且可以对其进行查找和计数。