Angular2 - 测试已调用注入的私有服务方法

Hom*_*rew 3 jasmine angular2-testing angular

首先,我理解我不应该测试私有方法,但是我觉得有时我应该测试是否基于某些逻辑调用了私有方法.

我正在围绕angular 2 http服务构建一个包装器服务,这样我就可以进行全局错误处理,而无需将代码写入每个http请求.

该类的一小部分样本如下:

export class ApiService {
  constructor(private http: Http, private error: Error, private apiConfig: ApiConfig) {}

  public get(url: string, options: RequestOptionsArgs={}): Observable<any> {
   return this.http.get(url, options).catch((error: any) => {
     this.error.dispatch(error);
     return error;
   });
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我想测试get方法并使用Error响应模拟响应以便catch触发,我无法测试是否调用了error.dispatch方法,因为这是私有的.我不能窥探私人方法.

你可能会争辩说我真的只是测试'catch'被解雇了,如果它确实显然内部的方法会被触发但是这只会测试http服务本身.我想确保在发送'catch'时将error.dispatch添加为调用,如果由于某种原因它被其他开发人员删除则会失败.也许这是一种不好的测试方法?我接受其他建议.

我可以像这样模拟私人课程:

{ provide: Error, useClass: FakeError }
Run Code Online (Sandbox Code Playgroud)

但是ApiService类的蓝图保持不变,现在的FakeError服务仍然是私有的.在Java中,您可以自己创建实例并注入它,因为您拥有它可以访问它.我想我正试图找到一种方法在jasmine/typescript/angular2中做到这一点?

Pau*_*tha 5

这是间谍可以提供帮助的地方.如果真实Error可以在没有DI的情况下实例化,那么你可以做到

let error;
beforeEach(()=>{
   error = new Error();
   spyOn(error, 'dispatch');

  TestBed.configureTestingModule({
    providers: [
      { provide: Error, useValue: error }
    ]
  });
});

it('', ()=> {
  expect(error.dispatch).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

或者你可以忘记Error课程并提供模拟.

class FakeError {
  dispatch = jasmine.createSpy('dispatch');
}
Run Code Online (Sandbox Code Playgroud)

就像上面一样使用它.你不需要spyOn像上面那样打电话.在这里,dispatch已经是间谍了.