我有一个sendMessage
方法,该方法调用了另一个服务(LoaderService
)show
方法。
sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> {
this.loaderService.show();
... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING
}
我正在尝试测试是否调用了show
方法,但是出现了错误Expected spy show to have been called.
。我可能做错了什么?我认为show
应该被调用,因为它是sendMessage
的第一行。
spec
是
describe('sendMessage function test suite: ',()=> {
let loader: LoaderService;
let httpClient:HttpClient;
let spy:any;
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'}),
withCredentials: true,
observe: 'events',
responseType: 'json'
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [HelperService, HttpClient, HttpHandler,LoaderService],
imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
});
});
fit('should show loader/spinner',
inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>{
const responseData = { result: 'success', ['additional-info']: 'some data from server' };
loader = new LoaderService();
spyOn(loader,'show'); //sendMessage calls show method of loader.
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
let helperService = TestBed.get(HelperService);
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>{
console.log('got response ',event);
});
expect(loader.show).toHaveBeenCalled();
}));
});
答案 0 :(得分:0)
您监视LoaderService
的另一个 实例。 spyOn函数用于将间谍程序安装到对象中,而不是全局安装。
您可以获得使用HelperService
注入到TestBed.get(LoaderService)
的实例。
答案 1 :(得分:0)
上面的Mixth解释是正确的。以下是我的看法,我认为我应该分享。
我想我以前的代码做错了几件事。据我了解,我可以通过3种方式进行测试
1)仅使用Jasmine和Karma,而不使用Testbed。这是一种通用方法。我用这种方法显式创建所需的类的实例。例如。
new LoaderService()
。
以上对于我自己定义的类(服务和组件)非常有效。但是,如果我的测试用例使用了某些Angular的模块(例如HttpClientModule
),那么最好使用TestBed
-“测试床是Angular的一项非常特定的功能,它将负责实例化组件,服务并负责使用DI的依赖项”
为确保测试用例始终都在引用一个类的同一实例,应在所有类的TestBed
个实例中使用extract
。
fit('should show loader/spinner',()=>{
let helperService = TestBed.get(HelperService);//extract helper service
let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
spyOn(loaderService,'show'); //sendMessage calls hide method of loader.
const responseData = { result: 'success', ['additional-info']: 'some data from server' };
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
/*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
HttpTestingController has methods which could mock sending a request
*/
let httpMock = TestBed.get(HttpTestingController);
//call the sendMessage function and subscribe to its observable.
let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
let subscription = result.subscribe((event:HttpEvent<any>)=>{
console.log('got response ',event);
});
const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
//once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
mockReq.flush(httpEvent); //flush method provides dummy values as response
httpMock.verify();//verify checks that there are no outstanding requests;
expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
});