Angular2 - 测试是否调用了注入的私有服务方法
Angular2 - test that a injected private service method has been called
首先,我明白我不应该测试私有方法,但是我觉得有时候我应该测试是否基于某些逻辑调用了私有方法。
我正在围绕 angular 2 http 服务构建一个包装器服务,这样我就可以进行全局错误处理,而不必将代码写入每个 http 请求。
class 的一个小样本是这样的:
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;
});
}
}
如果我想测试 get 方法并使用错误响应进行模拟响应,以便触发捕获,我无法测试是否调用了 error.dispatch 方法,因为这是私有的。我不能监视私有方法。
您可能会争辩说,我真的只是在测试 'catch' 是否被触发,如果确实如此,它内部的方法显然会被触发,但这只是在测试 http 服务本身。如果 'catch' 被触发,我想确保 error.dispatch 已添加为调用,如果由于某种原因被其他开发人员删除,则失败。也许这是一种糟糕的测试方式?我愿意接受其他建议。
我可以像这样模拟私有 class:
{ provide: Error, useClass: FakeError }
但 ApiService class 的蓝图保持不变,现在的 FakeError 服务仍然是私有的。在 Java 中,您可以自己创建实例并注入它,因为您拥有它,您可以访问它。我想我正试图在 jasmine/typescript/angular2 中找到一种方法来做到这一点 ??
这就是 spies 可以提供帮助的地方。如果真正的 Error
可以在没有 DI 的情况下实例化,你可以做
let error;
beforeEach(()=>{
error = new Error();
spyOn(error, 'dispatch');
TestBed.configureTestingModule({
providers: [
{ provide: Error, useValue: error }
]
});
});
it('', ()=> {
expect(error.dispatch).toHaveBeenCalled();
});
或者您可以忘记 Error
class 并提供一个模拟。
class FakeError {
dispatch = jasmine.createSpy('dispatch');
}
像上面一样使用它。不过,您不需要像上面那样调用 spyOn
。这里,dispatch
已经是间谍了。
首先,我明白我不应该测试私有方法,但是我觉得有时候我应该测试是否基于某些逻辑调用了私有方法。
我正在围绕 angular 2 http 服务构建一个包装器服务,这样我就可以进行全局错误处理,而不必将代码写入每个 http 请求。
class 的一个小样本是这样的:
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;
});
}
}
如果我想测试 get 方法并使用错误响应进行模拟响应,以便触发捕获,我无法测试是否调用了 error.dispatch 方法,因为这是私有的。我不能监视私有方法。
您可能会争辩说,我真的只是在测试 'catch' 是否被触发,如果确实如此,它内部的方法显然会被触发,但这只是在测试 http 服务本身。如果 'catch' 被触发,我想确保 error.dispatch 已添加为调用,如果由于某种原因被其他开发人员删除,则失败。也许这是一种糟糕的测试方式?我愿意接受其他建议。
我可以像这样模拟私有 class:
{ provide: Error, useClass: FakeError }
但 ApiService class 的蓝图保持不变,现在的 FakeError 服务仍然是私有的。在 Java 中,您可以自己创建实例并注入它,因为您拥有它,您可以访问它。我想我正试图在 jasmine/typescript/angular2 中找到一种方法来做到这一点 ??
这就是 spies 可以提供帮助的地方。如果真正的 Error
可以在没有 DI 的情况下实例化,你可以做
let error;
beforeEach(()=>{
error = new Error();
spyOn(error, 'dispatch');
TestBed.configureTestingModule({
providers: [
{ provide: Error, useValue: error }
]
});
});
it('', ()=> {
expect(error.dispatch).toHaveBeenCalled();
});
或者您可以忘记 Error
class 并提供一个模拟。
class FakeError {
dispatch = jasmine.createSpy('dispatch');
}
像上面一样使用它。不过,您不需要像上面那样调用 spyOn
。这里,dispatch
已经是间谍了。