我有一个服务,它在构造函数中进行 2 个方法调用:
constructor(private http: HttpClient) {
this.apiURL = environment.apiURL;
this.method();
this.method2().subscribe();
}
我正在尝试在测试平台中测试此服务。但是,我无法在TestBed.get(MyService)
之前利用茉莉的间谍进行间谍活动。
这是我服务的测试平台配置:
let myService: MyService;
let backend: HttpTestingController;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
HttpClientTestingModule
],
providers: [
MyService
]
}).compileComponents();
myService = TestBed.get(MyService);
backend = TestBed.get(HttpTestingController);
如何正确监视method()
和method2()
并为它们返回值。如果服务将方法放在构造函数中不是一种好的做法吗?
method()
和method2()
向服务器发送HTTP调用以"刷新"用户可能需要的数据,例如Posts
墙上的数据。另一种方法是设置为令牌期限的Observable.timer
,以便在令牌过期后自动注销应用。
如果method
和method2
是原型方法,则可以监视类原型:
it('', () => {
spyOn(MyService.prototype, 'method').and.callThrough();
spyOn(MyService.prototype, 'method2').and.callThrough();
const svc = TestBed.get(MyService);
expect(svc['method']).toHaveBeenCalled();
expect(svc['method2']).toHaveBeenCalled();
});
它始终取决于方法是否适合在构造函数中使用。
如果方法返回订阅,则应将其另存为属性,因为它可能会在以后取消订阅,例如在服务销毁时。
考虑到method
和method2
是异步的,这可能是一种反模式。如果它们触发预期在服务实例化时完成的请求,这将导致争用条件,因为它们未完成,并且服务也不会公开承诺或可观察量来跟踪请求的状态。正确的解决方案是不在构造函数中调用它们,而是在适合异步提供程序初始化的某个地方调用它们,即 APP_INITIALIZER
或路由解析器。