Angular 我无法使用BehaviorSubject正确配置角度服务测试以发出状态对象
我有一个服务,它进行api调用,然后在私有状态对象上设置值,然后向行为主体发出更新Angular 我无法使用BehaviorSubject正确配置角度服务测试以发出状态对象,angular,unit-testing,rxjs,behaviorsubject,angular-test,Angular,Unit Testing,Rxjs,Behaviorsubject,Angular Test,我有一个服务,它进行api调用,然后在私有状态对象上设置值,然后向行为主体发出更新 @Injectable({ providedIn: 'root' }) export class ExeService { private state: IState = { things: {} }; public things$: BehaviorSubject<{ [key: string]: IThing }> = new BehaviorSubject<{
@Injectable({
providedIn: 'root'
})
export class ExeService {
private state: IState = {
things: {}
};
public things$: BehaviorSubject<{ [key: string]: IThing }> = new BehaviorSubject<{ [key: string]: IThing }>(this.state.things);
constructor(
private http: HttpClient
) { }
public getThings() {
this.http.get('/api/things').subscribe({
next: (res) => {
this.state.things = res;
this.things$.next(this.state.things)
}
})
}
}
当测试执行时,它实际上执行getThings()
,并在req.flush
之前评估对行为主体的订阅。我从概念上理解,在提供所有测试参数之前,不应该评估整个过程。我最终得到了一个404请求http://localhost:9876/api/things
(karma测试端口),然后它发出测试请求。(我还收到大量来自SASS文件的404警告,试图获取不在我的应用程序目录中的字体文件,但这是另一回事)
为了评估我是否具有预期的值,我首先必须检查行为主体是否具有任何值,从而检查对象.keys(things).length
。我认为这实际上使测试无效,因为如果服务未能设置它,那么expect()
将永远不会发生,因此会出现误报。但是,如果我删除它,那么测试将失败,因为初始订阅结果返回{}
问题:我不明白这是如何工作的,还是我的测试配置完全不正确?我认为它首先评估订阅,因为您使用的是
行为子对象
。如果您的目的是验证BehaviorSubject是否发出了正确的数据,那么您可以创建一个模拟的things$
,并断言,例如things$。接下来使用正确的参数调用了。现在我还想知道这里是否需要HttpClientTestingModule
。我认为它会首先评估订阅,因为您使用的是行为主题。如果您的目的是验证BehaviorSubject是否发出了正确的数据,那么您可以创建一个模拟的things$
,并断言,例如things$。接下来使用正确的参数调用了。现在我还想知道这里是否需要HttpClientTestingModule
。
describe('ExeService', () => {
let injector: TestBed;
let service: ExeService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
ExeService
],
imports: [
HttpClientTestingModule
]
});
injector = getTestBed();
service = injector.get(ExeService);
httpMock = injector.get(HttpTestingController);
});
afterEach(() => {
httpMock.verify();
});
it('Should get things', (done) => {
service.getThings();
service.things$.subscribe(things => {
if (Object.keys(things).length) {
expect(things).toEqual(MockedThings_ApiResponse);
done();
}
});
const req = httpMock.expectOne(`/api/things`);
expect(req.request.method).toEqual('GET');
req.flush(MockedThings_ApiResponse);
});
});