无法使用 HttpTestController 在 Jasmine 和 Karma 中模拟 HttpClient
unable to mock HttpClient in Jasmine and Karma using HttpTestController
我正在测试 AuthService
,它使用另一个 HelperService
.
将用户登录信息发送到服务器
public authServiceSigninUser(user:UserSigninInfo):any{
console.log('In authServiceSigninUser. contacting server at '+this.API_URL +this.SIGNIN_USER_URL +" with user data "+user+ " with httpOptions "+httpOptions.withCredentials + ","+httpOptions.headers ); //TODOM password should be sent in encrypted format.
let signinInfo= new UserSigninAPI(user);
let body = JSON.stringify(signinInfo);
return this.helperService.sendMessage(this.SIGNIN_USER_URL,body,httpOptions)
}
我正在尝试按如下方式测试 authServiceSigninUser
方法,但是当我 运行 规范时,出现错误 TypeError: Cannot read property 'subscribe' of undefined
。好像是Observable
。为什么?测试规格为
describe('authServiceSigninUser test suite',()=>{
beforeEach(()=>{
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [AuthService, HelperService]
});
});
fit('should sign in user',()=>{
let spy:any;
let helper = TestBed.get(HelperService);
console.log("helper services is ",helper);
let authService = TestBed.get(AuthService);
console.log("auth services is ",authService);
let userSignIn = new UserSigninInfo("test@test.com","test");
let httpMock = TestBed.get(HttpTestingController);
spyOn(helper,'sendMessage');
const responseData = { result: 'success', ['additional-info']: 'login success' };
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
let observable:Observable<HttpEvent<any>> = authService.authServiceSigninUser(userSignIn);
console.log("observable ",observable);//this is undefined
let subscription = observable.subscribe((event)=>{ //error here
console.log('event from authService',event);
});
const mockReq:TestRequest = httpMock.expectOne(environment.apiUrl+environment.signinUserUrl); //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(helper.sendMessage).toHaveBeenCalled();
});
});
sendMessage
在 HelperService
中是
sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> {
this.loaderService.show();
let observable:Observable<HttpEvent<any>> = this.http.post<any>(url,body,httpOptions);
return observable.pipe(
tap((httpEvent:HttpEvent<any>) => {//tap transparently perform actions or side-effects, such as logging.
if(httpEvent.type === HttpEventType.Response)
{
console.log('response from backend service:', httpEvent);
}
else {
console.log("not an http response")
}
return httpEvent;
})
,catchError(err=>this.handleError(err))
,finalize(()=> this.loaderService.hide()));
}
我不知道为什么上面的测试不起作用,但我认为我对测试的一般方法是不正确的。由于我正在进行单元测试 AuthService
,我可能应该模拟我期望从依赖服务的方法获得的响应。例如,我应该 spyOn
sendMessage
和 return 一个模拟值。此外,我的目标应该是测试 sendMessage
是否使用正确的参数调用。
describe('authServiceSigninUser test suite',()=>{
beforeEach(()=>{
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],//need this as HelperSerice needs HttpClient and this module provides it. I could have also used HttpClientModule
providers: [AuthService, HelperService]
});
});
fit('should send request to sign in user',()=>{
// let spy:any;
let helper = TestBed.get(HelperService);
//console.log("helper services is ",helper);
let authService = TestBed.get(AuthService);
//console.log("auth services is ",authService);
let userSignIn = new UserSigninInfo("test@test.com","test"); //data to send to server
//response expected from sendMessage
const responseData = { result: 'success', ['additional-info']: 'login success' };
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
spyOn(helper,'sendMessage').and.returnValue(new Observable(()=>{
httpEvent
})); //when sendMessage is called, return the mocked response
let observable:Observable<HttpEvent<any>> = authService.authServiceSigninUser(userSignIn); //now when authServiceSignInUserr is called, it will call sendMessage and the spyOn will return mocked response
console.log("observable returned ",observable);
let subscription = observable.subscribe((event)=>{
console.log('event from authService',event);
});
//check that the arguments passed to sendMessage are correct
let APIToBeUsed = authService.SIGNIN_USER_URL;
let JSONToBeUsed = JSON.stringify(new UserSigninAPI(userSignIn));
let HTTPOptionsToBeUsed = authService.httpOptions;
expect(helper.sendMessage).toHaveBeenCalledWith(APIToBeUsed,jasmine.any(String),jasmine.any(Object));
expect(helper.sendMessage).toHaveBeenCalledWith(jasmine.any(String),JSONToBeUsed,jasmine.any(Object));
expect(helper.sendMessage).toHaveBeenCalledWith(jasmine.any(String),jasmine.any(String),HTTPOptionsToBeUsed);
});
});
我正在测试 AuthService
,它使用另一个 HelperService
.
public authServiceSigninUser(user:UserSigninInfo):any{
console.log('In authServiceSigninUser. contacting server at '+this.API_URL +this.SIGNIN_USER_URL +" with user data "+user+ " with httpOptions "+httpOptions.withCredentials + ","+httpOptions.headers ); //TODOM password should be sent in encrypted format.
let signinInfo= new UserSigninAPI(user);
let body = JSON.stringify(signinInfo);
return this.helperService.sendMessage(this.SIGNIN_USER_URL,body,httpOptions)
}
我正在尝试按如下方式测试 authServiceSigninUser
方法,但是当我 运行 规范时,出现错误 TypeError: Cannot read property 'subscribe' of undefined
。好像是Observable
。为什么?测试规格为
describe('authServiceSigninUser test suite',()=>{
beforeEach(()=>{
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [AuthService, HelperService]
});
});
fit('should sign in user',()=>{
let spy:any;
let helper = TestBed.get(HelperService);
console.log("helper services is ",helper);
let authService = TestBed.get(AuthService);
console.log("auth services is ",authService);
let userSignIn = new UserSigninInfo("test@test.com","test");
let httpMock = TestBed.get(HttpTestingController);
spyOn(helper,'sendMessage');
const responseData = { result: 'success', ['additional-info']: 'login success' };
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
let observable:Observable<HttpEvent<any>> = authService.authServiceSigninUser(userSignIn);
console.log("observable ",observable);//this is undefined
let subscription = observable.subscribe((event)=>{ //error here
console.log('event from authService',event);
});
const mockReq:TestRequest = httpMock.expectOne(environment.apiUrl+environment.signinUserUrl); //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(helper.sendMessage).toHaveBeenCalled();
});
});
sendMessage
在 HelperService
中是
sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> {
this.loaderService.show();
let observable:Observable<HttpEvent<any>> = this.http.post<any>(url,body,httpOptions);
return observable.pipe(
tap((httpEvent:HttpEvent<any>) => {//tap transparently perform actions or side-effects, such as logging.
if(httpEvent.type === HttpEventType.Response)
{
console.log('response from backend service:', httpEvent);
}
else {
console.log("not an http response")
}
return httpEvent;
})
,catchError(err=>this.handleError(err))
,finalize(()=> this.loaderService.hide()));
}
我不知道为什么上面的测试不起作用,但我认为我对测试的一般方法是不正确的。由于我正在进行单元测试 AuthService
,我可能应该模拟我期望从依赖服务的方法获得的响应。例如,我应该 spyOn
sendMessage
和 return 一个模拟值。此外,我的目标应该是测试 sendMessage
是否使用正确的参数调用。
describe('authServiceSigninUser test suite',()=>{
beforeEach(()=>{
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],//need this as HelperSerice needs HttpClient and this module provides it. I could have also used HttpClientModule
providers: [AuthService, HelperService]
});
});
fit('should send request to sign in user',()=>{
// let spy:any;
let helper = TestBed.get(HelperService);
//console.log("helper services is ",helper);
let authService = TestBed.get(AuthService);
//console.log("auth services is ",authService);
let userSignIn = new UserSigninInfo("test@test.com","test"); //data to send to server
//response expected from sendMessage
const responseData = { result: 'success', ['additional-info']: 'login success' };
let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
spyOn(helper,'sendMessage').and.returnValue(new Observable(()=>{
httpEvent
})); //when sendMessage is called, return the mocked response
let observable:Observable<HttpEvent<any>> = authService.authServiceSigninUser(userSignIn); //now when authServiceSignInUserr is called, it will call sendMessage and the spyOn will return mocked response
console.log("observable returned ",observable);
let subscription = observable.subscribe((event)=>{
console.log('event from authService',event);
});
//check that the arguments passed to sendMessage are correct
let APIToBeUsed = authService.SIGNIN_USER_URL;
let JSONToBeUsed = JSON.stringify(new UserSigninAPI(userSignIn));
let HTTPOptionsToBeUsed = authService.httpOptions;
expect(helper.sendMessage).toHaveBeenCalledWith(APIToBeUsed,jasmine.any(String),jasmine.any(Object));
expect(helper.sendMessage).toHaveBeenCalledWith(jasmine.any(String),JSONToBeUsed,jasmine.any(Object));
expect(helper.sendMessage).toHaveBeenCalledWith(jasmine.any(String),jasmine.any(String),HTTPOptionsToBeUsed);
});
});