[英]How to unit test Observable.zip(observable1, observable2)
I'm trying to unit test a component that uses a Observable.zip() 我正在尝试对使用Observable.zip()的组件进行单元测试
As you can see the BehaviorSubject is initialized with null but in the beforeAll of the test code I force him to return an Observable.of 如您所见, 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;
}
}
Here it blows up. 在这里,它炸毁了。 When it subscribes to the Observable.zip and tries to fetch the result[1] from it, this result is NULL.
当它订阅Observable.zip并尝试从中获取result [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;
});
It looks like the result[1] of the zipped observable doesn't return a value. 看起来可压缩的observable的result [1]没有返回值。 I also tried to switch Observable.zip with Observable.combineLatest, but without any result.
我也尝试用Observable.combineLatest切换Observable.zip,但没有任何结果。 The error is the same.
错误是一样的。
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
});
});
Even converting the property $profilo into a getter and spying on it returning a value, nothing changes... 即使将$ profilo属性转换为吸气剂并监视返回值,也没有任何变化...
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();
});
});
Am I missing something? 我想念什么吗? I'm on this problem since yesterday morning and I'm about to crash my workstation on the floor.
自昨天早上以来,我就一直在处理此问题,而我的工作站正要崩溃。 Any help is really appreciated (by the machine :P)
真的很感谢任何帮助(通过机器:P)
Leaving aside the unit test, seems to me it's impossible for zip()
to emit result where result[1] is null, unless this.profiloUtenteService.$profilo
is emitting a null. 撇开单元测试,在我看来,
zip()
不可能在result [1]为null的情况下发出结果,除非this.profiloUtenteService.$profilo
发出的是null。
Quick test, try 快速测试,尝试
this.profiloUtenteService.$profilo
.filter(x => x)
Edit for service mock 编辑服务模拟
When I use .and.returnValue
I create the mock with jasmine, 当我使用
.and.returnValue
我用茉莉花创建了模拟,
const mockService = jasmine.createSpyObj('ProfiloUtenteService ', ['$profilo']);
mockService.$profilo.and.returnValue(...)
Your code may be ok too, but above works for me. 您的代码也可以,但是上面的代码对我有用。
Note that sometimes a dependency doesn't get created, but no error is raised. 请注意,有时不会创建依赖项,但不会引发错误。 Perhaps the base class of the service is causing a fail, I can't see it in the providers list.
服务的基类可能导致失败,我在提供程序列表中看不到它。 Using a completely detach mock from jasmine will eliminate that.
使用完全独立的茉莉花模拟可以消除这种情况。
I was working on the wrong spec file. 我正在处理错误的规格文件。 The tests where starting from app.component.spec.ts but the error was thrown from the pratiche.component.ts so I wrongly thought that the error were in the pratiche.component.spec.ts while the mock were required by the app.component.spec.ts Copy and pasting the code from a file to another fixed everything
测试从app.component.spec.ts开始,但是错误是从pratiche.component.ts引发的,所以我错误地认为错误是在pratiche.component.spec.ts中,而应用程序需要模拟。 component.spec.ts将代码从文件复制并粘贴到另一个固定的内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.