Угловой тест Жасмин не стреляет подписаться внутри ngOnInit - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть базовый класс компонентов, внутри ngOnInit он подписывается на вызов службы

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

Поэтому я включил этот console.log, чтобы посмотреть, будет ли когда-либо выполняться эта подписка.

В моем тесте я включил этот метод службы активности, чтобы вернуть наблюдаемую коллекцию нужных мне данных. Затем в тесте я выполняю весь процесс 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 Ответ

0 голосов
/ 14 ноября 2018

После нескольких часов попыток использования fakeAsync, предоставления имитационного класса для сервиса, различных вызовов tick (), десятков других сообщений и немного разных подходов, виновник добавил одну строку: component.ngOnInit();.

По-видимому, хотя fixture.detectChanges() определенно вызывает ngOnInit, это как-то удерживало наблюдаемый холод.Когда я звонил бы fixture.detectChanges(), это не входило бы в подписку наблюдаемого.Как только я добавил component.ngOnInit(), наблюдаемая стала горячей, и код внутри подписки был выполнен, и я увидел распечатанные журналы моей консоли.Как это ни странно, следующие fixture.detectChanges() вызовы также переходят в код подписки для каждого последующего вызова.

Вот упрощенная версия моего спецификационного файла, надеюсь, это поможет любому в будущем с той же проблемой.Зоны fakeAsync и sync по-прежнему проходили тест, я предполагал, что мне потребуется хотя бы tick () внутри зоны fakeAsync, но в этом не было необходимости.

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);
});

});

...