我正在尝试对使用Observable.zip()
的组件进行单元测试正如您所看到的 BehaviorSubject 已使用 null 进行初始化,但在测试代码的 beforeAll 中,我强制他返回 Observable.of
export class ProfiloUtenteService extends BaseService<ProfiloDto> {
public static readonly profiloKey = 'profiloUtente';
private _$profilo = new BehaviorSubject<ProfiloDto>(null);
public $profilo = this._$profilo.asObservable();
protected get storedProfilo(): ProfiloDto {
const profilo = this.storageService.retrieve(ProfiloUtenteService.profiloKey);
return profilo ? profilo : null;
}
protected set storedProfilo(profilo: ProfiloDto) {
this.storageService.store(ProfiloUtenteService.profiloKey, profilo);
this._$profilo.next(profilo);
}
private emptyProfile = {
addettoId: null,
scope: Scope.none,
selectedScope: Scope.none,
ufficioId: null,
provinciaUfficioId: null,
addettoCognome: null,
addettoNome: null
};
constructor(
protected httpClient: HttpClient,
protected appConfig: AppConfig,
protected storageService: StorageService
) {
super(httpClient, appConfig, appConfig.endpoints.addetto.api.baseUrl);
const profilo = this.storedProfilo;
if (profilo) {
this._$profilo.next(profilo);
}
}
public updateProfiloUtente(): void {
const readProfilo = this.storedProfilo;
if (readProfilo) {
this._$profilo.next(readProfilo);
}else {
super.get((<AppConfig>this.appConfig).endpoints.addetto.api.routes.profilo)
.takeLast(1)
.do(profilo => {
if (!profilo) {
this._$profilo.next(this.emptyProfile);
}
})
.filter(profilo => !!profilo)
.subscribe(profilo => {
profilo.selectedScope = Scope.all;
this.storedProfilo = profilo;
});
}
}
public setSelectedScope(scope: Scope) {
const profilo = this.storedProfilo;
if (profilo) {
profilo.selectedScope = scope;
this.storedProfilo = profilo;
}
}
public setSelectedUfficioId(ufficioId: number, provinciaUfficioId?: number) {
const profilo = this.storedProfilo;
if (profilo) {
profilo.ufficioId = ufficioId;
profilo.provinciaUfficioId = provinciaUfficioId || null;
this.storedProfilo = profilo;
}
}
public logout() {
this.storedProfilo = null;
}
}
这里爆炸了。当它订阅Observable.zip并尝试从中获取结果[1]时,此结果为NULL。
Observable.zip(
this.ufficioService.getODataForCombo({ skip: 0 }),
this.profiloUtenteService.$profilo)
.takeWhile(() => this.isAlive)
.subscribe(result => {
result[0].forEach(office => this.availableOffices.push(office));
// when this point is reached an error is thrown
this.selectedOfficeId = result[1].ufficioId;
this.selectedOfficeDescription = this.availableOffices.find(office => office.id === this.selectedOfficeId).descrizione;
});
看起来压缩的observable的结果[1]不返回值。我也尝试用Observable.combineLatest切换Observable.zip,但没有任何结果。错误是一样的。
beforeAll(() => {
ufficioServiceMock = new UfficioService(null, fixedAppConfig);
spyOn(ufficioServiceMock, 'getODataForCombo').and.returnValue(Observable.of([]));
profiloUtenteServiceMock = new ProfiloUtenteService(null, fixedAppConfig, null);
profiloUtenteServiceMock.$profilo = Observable.of({
addettoId: 1,
ufficioId: 1,
provinciaUfficioId: 1,
scope: 1,
addettoNome: 'string',
addettoCognome: 'string',
selectedScope: 1
});
});
甚至将属性$ profilo转换为getter并监视它返回一个值,没有任何变化......
describe('PraticheSearchComponent', () => {
let comp: PraticheSearchComponent;
let fixture: ComponentFixture<PraticheSearchComponent>;
let de: DebugElement;
let el: HTMLElement;
let ufficioServiceMock: UfficioService;
let profiloUtenteServiceMock: ProfiloUtenteService;
beforeAll(() => {
ufficioServiceMock = new UfficioService(null, fixedAppConfig);
spyOn(ufficioServiceMock, 'getODataForCombo').and.returnValue(Observable.of([]));
profiloUtenteServiceMock = new ProfiloUtenteService(null, fixedAppConfig, null);
spyOn(profiloUtenteServiceMock, '$profilo').and.returnValue(new BehaviorSubject({
addettoId: 1,
ufficioId: 1,
provinciaUfficioId: 1,
scope: 1,
addettoNome: 'string',
addettoCognome: 'string',
selectedScope: 1
}).asObservable());
});
// profiloUtenteServiceMock.$profilo = new BehaviorSubject({
// addettoId: 1,
// ufficioId: 1,
// provinciaUfficioId: 1,
// scope: 1,
// addettoNome: 'string',
// addettoCognome: 'string',
// selectedScope: 1
// }).asObservable();
// });
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
PraticheSearchComponent
],
imports: [
NgProgressModule,
AuthModule.forRoot(),
CustomHttpHeadersModule.forRoot(),
SharedModule.forRoot(),
ReactiveFormsModule,
PatronatoSharedModule,
FrameworkCoreModule.forRoot(),
LoggerModule.forRoot(Level.LOG),
MaterialModule,
BrowserAnimationsModule,
RouterTestingModule.withRoutes([])
],
providers: [
{ provide: AppConfig, useValue: fixedAppConfig },
{ provide: LocalizationKeys, useValue: new LocalizationKeys() },
{ provide: ProfiloUtenteService, useValue: profiloUtenteServiceMock },
{ provide: NavbarService, useValue: new NavbarServiceMock() },
{ provide: PraticheSearchService, useValue: new PraticheSearchServiceMock() },
{ provide: UfficioService, useValue: ufficioServiceMock }
]
}).compileComponents();
fixture = TestBed.createComponent(PraticheSearchComponent);
comp = fixture.componentInstance;
de = fixture.debugElement;
el = de.nativeElement;
}));
it('should create', () => {
expect(comp).toBeTruthy();
});
});
我错过了什么吗?我从昨天早上起就遇到了这个问题,我即将把我的工作站撞到地板上。任何帮助都非常感谢(通过机器:P)
答案 0 :(得分:1)
除了单元测试之外,在我看来,zip()
不可能在结果[1]为空时发出结果,除非this.profiloUtenteService.$profilo
发出空值。
快速测试,试试
this.profiloUtenteService.$profilo
.filter(x => x)
编辑服务模拟
当我使用.and.returnValue
时,我使用jasmine创建模拟,
const mockService = jasmine.createSpyObj('ProfiloUtenteService ', ['$profilo']);
mockService.$profilo.and.returnValue(...)
您的代码也可以,但上面的内容对我来说很有用 请注意,有时不会创建依赖项,但不会引发错误。也许服务的基类导致失败,我无法在提供者列表中看到它。使用来自茉莉花的完全分离模拟将消除这种情况。
答案 1 :(得分:0)
我正在处理错误的规范文件。测试从 app.component.spec.ts 开始,但错误是从 pratiche.component.ts <强>所以我错误地认为错误在于 pratiche.component.spec.ts ,而 app.component.spec.ts 需要模拟 复制并将代码从文件粘贴到另一个修复所有内容