http.post 在使用 karma+jasmine 测试 angular2 服务时不是函数错误
http.post is not a function error while testing angular2 service with karma+jasmine
我正在尝试使用模拟后端测试我的 angular2 服务,但我的 http.post 服务请求一直收到此错误。
这里是错误:enter image description here
我的服务代码是:
@Injectable()
export class AuthService {
private _jwt: string;
constructor(private router: Router, private http: Http, private locker: Locker,
private authHttp: AuthHttp, private jwtHelper: JwtHelper) {
this._jwt = localStorage.getItem('id_token');
}
public signIn(user: any) {
let body = JSON.stringify(user);
let self = this;
return this.http.post(loginPath, body, {
headers: contentHeaders})
.map( function (response) { //some code here}
}
And my spec file is as follows:
import { TestBed, async, inject } from '@angular/core/testing';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import {
Http, BaseRequestOptions, ResponseOptions, Response, RequestMethod,
HttpModule, XHRBackend
} from '@angular/http';
import { Locker } from 'angular2-locker';
import { AuthHttp, JwtHelper } from 'angular2-jwt';
import { MockBackend, MockConnection } from '@angular/http/testing';
class RouterStub {
navigate() {
}
}
describe('Auth Service Unit Tests', () => {
let authService: AuthService = new AuthService(Router, Http, Locker, AuthHttp, JwtHelper );
let mockbackend;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{provide: Router, useClass: RouterStub},
{provide: AuthService, userValue: authService},
{
provide: Http,
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
}
],
imports: [
HttpModule
]
});
mockbackend = TestBed.get(MockBackend);
/* const baseResponse = new Response(new ResponseOptions({body: 'response'}));
mockbackend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));*/
}));
it('should respond when we subscribe to Sign in', async(() => {
mockbackend.connections.subscribe((connection: MockConnection) =>{
expect(connection.request.method).toBe(RequestMethod.Post);
connection.mockRespond(new Response(new ResponseOptions({status: 201})));
});
let user = {email: 'test@sample.com', password: '12345'};
authService.signIn(user).subscribe((res: Response) => {
expect(res).toBeDefined();
expect(res.status).toBe(200);
});
}));
});
非常感谢任何帮助!提前致谢
快速更新(根据@Will 的建议):我对我的服务实例进行了更改,如图所示
{provide: AuthService, useClass: AuthService}
并在我的测试规范中使用它如下:
authService = TestBed.get(AuthService, null)
但我仍然得到如下错误:
Failed: authService.signIn is not a function
TypeError: authService.signIn is not a function
at src/base.spec.ts:57308:21
我希望像下面这样的东西能起作用。如果继续出现 TypeError: authService.signIn is not a function
之类的错误,您可能会检查 AuthService 是否正确导出和导入。要调试 authService 实例,您可以添加注释 console.log
。在我编写的类似测试中,我发现不需要您拥有的 async()
包装器。
@Injectable()
export class AuthService {
private _jwt: string;
constructor(private router: Router, private http: Http, private locker: Locker,
private authHttp: AuthHttp, private jwtHelper: JwtHelper) {
this._jwt = localStorage.getItem('id_token');
}
public signIn(user: any) {
let body = JSON.stringify(user);
let self = this;
return this.http.post(loginPath, body, {
headers: contentHeaders})
.map( function (response) { //some code here}
}
And my spec file is as follows:
import { TestBed, async, inject } from '@angular/core/testing';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import {
Http, BaseRequestOptions, ResponseOptions, Response, RequestMethod,
HttpModule, XHRBackend
} from '@angular/http';
import { Locker } from 'angular2-locker';
import { AuthHttp, JwtHelper } from 'angular2-jwt';
import { MockBackend, MockConnection } from '@angular/http/testing';
class RouterStub {
navigate() {
}
}
describe('Auth Service Unit Tests', () => {
let authService: AuthService;
let mockbackend;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{provide: Router, useClass: RouterStub},
{provide: AuthService, useClass: AuthService},
{
provide: Http,
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
}
],
imports: [
HttpModule
]
});
mockbackend = TestBed.get(MockBackend);
authService = TestBed.get(AuthService, null);
/* const baseResponse = new Response(new ResponseOptions({body: 'response'}));
mockbackend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));*/
}));
it('should respond when we subscribe to Sign in', async(() => {
// console.log(JSON.stringify(authService));
mockbackend.connections.subscribe((connection: MockConnection) =>{
expect(connection.request.method).toBe(RequestMethod.Post);
connection.mockRespond(new Response(new ResponseOptions({status: 201})));
});
let user = {email: 'test@sample.com', password: '12345'};
authService.signIn(user).subscribe((res: Response) => {
expect(res).toBeDefined();
expect(res.status).toBe(200);
});
}));
});
如果这不起作用,我对这类问题的一般建议是,从 official Angular docs or a detailed blog like this 的示例测试开始,然后在本地为您 运行 获取它。然后慢慢更新测试,直到满足你的需求。
我正在尝试使用模拟后端测试我的 angular2 服务,但我的 http.post 服务请求一直收到此错误。
这里是错误:enter image description here
我的服务代码是:
@Injectable()
export class AuthService {
private _jwt: string;
constructor(private router: Router, private http: Http, private locker: Locker,
private authHttp: AuthHttp, private jwtHelper: JwtHelper) {
this._jwt = localStorage.getItem('id_token');
}
public signIn(user: any) {
let body = JSON.stringify(user);
let self = this;
return this.http.post(loginPath, body, {
headers: contentHeaders})
.map( function (response) { //some code here}
}
And my spec file is as follows:
import { TestBed, async, inject } from '@angular/core/testing';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import {
Http, BaseRequestOptions, ResponseOptions, Response, RequestMethod,
HttpModule, XHRBackend
} from '@angular/http';
import { Locker } from 'angular2-locker';
import { AuthHttp, JwtHelper } from 'angular2-jwt';
import { MockBackend, MockConnection } from '@angular/http/testing';
class RouterStub {
navigate() {
}
}
describe('Auth Service Unit Tests', () => {
let authService: AuthService = new AuthService(Router, Http, Locker, AuthHttp, JwtHelper );
let mockbackend;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{provide: Router, useClass: RouterStub},
{provide: AuthService, userValue: authService},
{
provide: Http,
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
}
],
imports: [
HttpModule
]
});
mockbackend = TestBed.get(MockBackend);
/* const baseResponse = new Response(new ResponseOptions({body: 'response'}));
mockbackend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));*/
}));
it('should respond when we subscribe to Sign in', async(() => {
mockbackend.connections.subscribe((connection: MockConnection) =>{
expect(connection.request.method).toBe(RequestMethod.Post);
connection.mockRespond(new Response(new ResponseOptions({status: 201})));
});
let user = {email: 'test@sample.com', password: '12345'};
authService.signIn(user).subscribe((res: Response) => {
expect(res).toBeDefined();
expect(res.status).toBe(200);
});
}));
});
非常感谢任何帮助!提前致谢
快速更新(根据@Will 的建议):我对我的服务实例进行了更改,如图所示
{provide: AuthService, useClass: AuthService}
并在我的测试规范中使用它如下:
authService = TestBed.get(AuthService, null)
但我仍然得到如下错误:
Failed: authService.signIn is not a function
TypeError: authService.signIn is not a function
at src/base.spec.ts:57308:21
我希望像下面这样的东西能起作用。如果继续出现 TypeError: authService.signIn is not a function
之类的错误,您可能会检查 AuthService 是否正确导出和导入。要调试 authService 实例,您可以添加注释 console.log
。在我编写的类似测试中,我发现不需要您拥有的 async()
包装器。
@Injectable()
export class AuthService {
private _jwt: string;
constructor(private router: Router, private http: Http, private locker: Locker,
private authHttp: AuthHttp, private jwtHelper: JwtHelper) {
this._jwt = localStorage.getItem('id_token');
}
public signIn(user: any) {
let body = JSON.stringify(user);
let self = this;
return this.http.post(loginPath, body, {
headers: contentHeaders})
.map( function (response) { //some code here}
}
And my spec file is as follows:
import { TestBed, async, inject } from '@angular/core/testing';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import {
Http, BaseRequestOptions, ResponseOptions, Response, RequestMethod,
HttpModule, XHRBackend
} from '@angular/http';
import { Locker } from 'angular2-locker';
import { AuthHttp, JwtHelper } from 'angular2-jwt';
import { MockBackend, MockConnection } from '@angular/http/testing';
class RouterStub {
navigate() {
}
}
describe('Auth Service Unit Tests', () => {
let authService: AuthService;
let mockbackend;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{provide: Router, useClass: RouterStub},
{provide: AuthService, useClass: AuthService},
{
provide: Http,
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
}
],
imports: [
HttpModule
]
});
mockbackend = TestBed.get(MockBackend);
authService = TestBed.get(AuthService, null);
/* const baseResponse = new Response(new ResponseOptions({body: 'response'}));
mockbackend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));*/
}));
it('should respond when we subscribe to Sign in', async(() => {
// console.log(JSON.stringify(authService));
mockbackend.connections.subscribe((connection: MockConnection) =>{
expect(connection.request.method).toBe(RequestMethod.Post);
connection.mockRespond(new Response(new ResponseOptions({status: 201})));
});
let user = {email: 'test@sample.com', password: '12345'};
authService.signIn(user).subscribe((res: Response) => {
expect(res).toBeDefined();
expect(res.status).toBe(200);
});
}));
});
如果这不起作用,我对这类问题的一般建议是,从 official Angular docs or a detailed blog like this 的示例测试开始,然后在本地为您 运行 获取它。然后慢慢更新测试,直到满足你的需求。