如何在注入服务中模拟 observable 属性?
How to mock observable property in injected service?
请帮我修复测试,我不知道如何修复它。看起来流中有不同的注入服务实例。我已经创建了我的代码的简化版本,就在这里。
我正在尝试模拟 observable facade.dataA$ = of(999);但是这部分完全被忽略了。
当前结果:
import { Injectable } from "@angular/core";
import { TestBed, waitForAsync } from '@angular/core/testing';
import { Observable, of } from "rxjs";
import { map, withLatestFrom } from "rxjs/operators";
export class OptionsFacade {
dataA$: Observable<number> = of(100);
dataB$: Observable<number> = of(500);
}
@Injectable()
export class TestService {
private options$: Observable<number[]> = this.optionsFacade.dataA$.pipe(
withLatestFrom(this.optionsFacade.dataB$),
map(([ valueA, valueB ]) => {
return [ valueA, valueB ];
}),
);
constructor(private optionsFacade: OptionsFacade) {
}
getOptions(): Observable<any> {
return this.options$.pipe(
map(([ val1, val2 ]) => {
return { val1, val2 };
}),
);
}
}
describe('TestService', () => {
let service: TestService;
let facade: OptionsFacade;
beforeAll(() => {
TestBed.configureTestingModule({
providers: [
TestService,
OptionsFacade,
],
});
service = TestBed.inject(TestService);
facade = TestBed.inject(OptionsFacade);
});
describe('getServerSelectedOptionsUids', () => {
it('should be array with one item', waitForAsync(() => {
facade.dataA$ = of(999);
service.getOptions().subscribe(data => {
expect(data).toEqual({ val1: 999, val2: 500 });
});
}));
});
});
OptionsFacade
属性应该是 BehaviorSubject
类型——一个既是观察者又是可观察者的流。然后您可以为它们分配新的值。 Observable 是只读流。
About subjects in RxJs documentation.
通过调用 .next(value)
完成分配(请参阅下面我的代码中的注释)
所以你的代码应该是:
export class OptionsFacade {
dataA$ = new BehaviorSubject<number>(100); // HERE
dataB$ = new BehaviorSubject<number>(500);
}
@Injectable({ providedIn: 'any' })
export class TestService {
private options$: Observable<number[]> = this.optionsFacade.dataA$.pipe(
withLatestFrom(this.optionsFacade.dataB$),
map(([valueA, valueB]) => [valueA, valueB]),
);
constructor(private optionsFacade: OptionsFacade) {
}
getOptions(): Observable<any> {
return this.options$
.pipe(
map(([val1, val2]) => ({ val1, val2 })
));
}
}
describe('TestService', () => {
let service: TestService;
let facade: OptionsFacade;
beforeAll(() => {
TestBed.configureTestingModule({
providers: [
TestService,
OptionsFacade
],
});
service = TestBed.inject(TestService);
facade = TestBed.inject(OptionsFacade);
});
describe('getServerSelectedOptionsUids', () => {
it('should be array with one item', waitForAsync(() => {
facade.dataA$.next(999); // AND HERE
service.getOptions().subscribe(data => {
expect(data).toEqual({ val1: 999, val2: 500 });
});
}));
});
});
请帮我修复测试,我不知道如何修复它。看起来流中有不同的注入服务实例。我已经创建了我的代码的简化版本,就在这里。
我正在尝试模拟 observable facade.dataA$ = of(999);但是这部分完全被忽略了。
当前结果:
import { Injectable } from "@angular/core";
import { TestBed, waitForAsync } from '@angular/core/testing';
import { Observable, of } from "rxjs";
import { map, withLatestFrom } from "rxjs/operators";
export class OptionsFacade {
dataA$: Observable<number> = of(100);
dataB$: Observable<number> = of(500);
}
@Injectable()
export class TestService {
private options$: Observable<number[]> = this.optionsFacade.dataA$.pipe(
withLatestFrom(this.optionsFacade.dataB$),
map(([ valueA, valueB ]) => {
return [ valueA, valueB ];
}),
);
constructor(private optionsFacade: OptionsFacade) {
}
getOptions(): Observable<any> {
return this.options$.pipe(
map(([ val1, val2 ]) => {
return { val1, val2 };
}),
);
}
}
describe('TestService', () => {
let service: TestService;
let facade: OptionsFacade;
beforeAll(() => {
TestBed.configureTestingModule({
providers: [
TestService,
OptionsFacade,
],
});
service = TestBed.inject(TestService);
facade = TestBed.inject(OptionsFacade);
});
describe('getServerSelectedOptionsUids', () => {
it('should be array with one item', waitForAsync(() => {
facade.dataA$ = of(999);
service.getOptions().subscribe(data => {
expect(data).toEqual({ val1: 999, val2: 500 });
});
}));
});
});
OptionsFacade
属性应该是 BehaviorSubject
类型——一个既是观察者又是可观察者的流。然后您可以为它们分配新的值。 Observable 是只读流。
About subjects in RxJs documentation.
通过调用 .next(value)
完成分配(请参阅下面我的代码中的注释)
所以你的代码应该是:
export class OptionsFacade {
dataA$ = new BehaviorSubject<number>(100); // HERE
dataB$ = new BehaviorSubject<number>(500);
}
@Injectable({ providedIn: 'any' })
export class TestService {
private options$: Observable<number[]> = this.optionsFacade.dataA$.pipe(
withLatestFrom(this.optionsFacade.dataB$),
map(([valueA, valueB]) => [valueA, valueB]),
);
constructor(private optionsFacade: OptionsFacade) {
}
getOptions(): Observable<any> {
return this.options$
.pipe(
map(([val1, val2]) => ({ val1, val2 })
));
}
}
describe('TestService', () => {
let service: TestService;
let facade: OptionsFacade;
beforeAll(() => {
TestBed.configureTestingModule({
providers: [
TestService,
OptionsFacade
],
});
service = TestBed.inject(TestService);
facade = TestBed.inject(OptionsFacade);
});
describe('getServerSelectedOptionsUids', () => {
it('should be array with one item', waitForAsync(() => {
facade.dataA$.next(999); // AND HERE
service.getOptions().subscribe(data => {
expect(data).toEqual({ val1: 999, val2: 500 });
});
}));
});
});