我正在尝试对Angular中的Resolver服务进行单元测试。我的测试用例之一是通过transferState(服务器端渲染)设置值。我将在getHomePageData
可观察的管道中执行此操作。注意,我嘲笑了该方法返回的内容。
我正在尝试使用fakeAsync。调用`flush()'(之前尝试过tick()),我希望它能进入管道,但事实并非如此。我在这里做什么错了?
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { Resolve } from '@angular/router';
import { makeStateKey, TransferState, StateKey } from '@angular/platform-browser';
import { isPlatformServer } from '@angular/common';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ScienceStoryService } from '../../core/science-story/science-story.service';
import { HomePage } from './home-page';
@Injectable()
export class HomePageResolveService implements Resolve<HomePage> {
constructor(private readonly scienceStoryService: ScienceStoryService,
@Inject(PLATFORM_ID) private readonly platformId,
private readonly transferState: TransferState) { }
resolve(): Observable<HomePage> {
const HOMEPAGE_DATA_KEY: StateKey<HomePage> = this.getStateKey('homepage-data');
if (this.transferState.hasKey(HOMEPAGE_DATA_KEY)) {
const homePageData = this.transferState.get<HomePage>(HOMEPAGE_DATA_KEY, null);
this.transferState.remove(HOMEPAGE_DATA_KEY);
return of(homePageData);
} else {
return this.scienceStoryService.getHomePageData()
.pipe(
tap((homePageData: HomePage) => {
if (this.isPlatformServer()) {
this.transferState.set(HOMEPAGE_DATA_KEY, homePageData);
}
})
);
}
}
getStateKey(keyName: string): StateKey<HomePage> {
return makeStateKey<HomePage>(keyName);
}
isPlatformServer(): boolean {
return isPlatformServer(this.platformId);
}
}
单元测试:
it('should set transfer state while running on server', fakeAsync(() => {
spyOn(service, 'getStateKey').and.returnValue(makeStateKey<HomePage>('non-existing-key'));
const scienceStoryService = TestBed.get(ScienceStoryService);
spyOn(scienceStoryService, 'getHomePageData').and.returnValue(of({}));
const transferState = TestBed.get(TransferState);
spyOn(service, 'isPlatformServer').and.returnValue(true);
spyOn(transferState, 'set');
service.resolve();
flush();
expect(transferState.set).toHaveBeenCalledTimes(1);
}));