模拟服务以调用本地 json-server 而不是远程端点 - 测试语法? (Angular 2)
Mocking a service to call local json-server instead of remote endpoint - test syntax? (Angular 2)
我正在尝试编写一个单元测试以确定 属性 在我的 angular 2 组件上填充 returns 承诺后的服务调用。
我的组件包含一个方法:
getListItems() {
this.employeeService.loadEmployees().then(res => {
this._employees = res['Employees'];
this.ref.markForCheck();
});
};
在服务上调用方法:
@Injectable()
export class EmployeeService {
constructor(
public http: Http
) { }
public loadEmployees(): Promise<any> {
return this.http.get('employees.json')
.map((res: Response) => res.json())
.toPromise();
}
}
从本地 json 文件中获取内容(代替创建远程端点)。这很好用,但我想在测试时用调用本地 json-server 的方法替换服务方法。
据我所知,在 Karma 测试 运行 时,我已经让 json-服务器正确旋转 up/down - 我可以使用 Postman 成功执行 GET 请求测试 运行ning.
因此我想用 mock 替换我的服务:
class MockEmployeeService {
headers: Headers;
constructor(private http: Http) {
this.headers = new Headers({ 'Content-Type': 'application/json' });
}
public loadEmployees() {
return this.http.get('http://localhost:3004/getEmployees',
{headers: this.headers, body: '' })
.map((res: Response) => res.json());
}
}
并且我已经按如下方式设置了单元测试:
describe('ListComponent', () => {
let fixture;
let component;
let employeeService;
beforeEach( async(() => {
TestBed.configureTestingModule({
imports: [
HttpModule
],
declarations: [
ListComponent
],
providers: [
{provide: EmployeeService, useClass: MockEmployeeService}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListComponent);
component = fixture.componentInstance;
employeeService = fixture.debugElement.injector
.get(EmployeeService);
});
it('should retrieve test values from json-server (async)',
async(() => {
fixture.detectChanges();
component.getListItems();
fixture.whenStable.then(() => {
expect(component._employees).toBeDefined();
});
}));
})
所以(我认为)我在应该调用服务的组件上调用方法,应该用 MockEmployeeService
替换。我收到以下 Karma 错误:
× should retrieve test values from json-server (async)
PhantomJS 2.1.1 (Windows 7 0.0.0)
Failed: Can't resolve all parameters for MockEmployeeService: (?).
在这一点上,我几乎处于我的知识范围内,我很难找到用于较新的、使用 TestBed 的测试的在线资源。有谁能看出这里有什么不对劲的地方吗?
如果您正在模拟该服务,则不应使用 Http
。只是 return 你自己的承诺,不与 Http
.
互动
class MockEmployeeService {
public loadEmployees() {
return Promise.resolve({some:'object'});
}
}
使用 Http
服务,您将进行 XHR 调用,这在测试期间是您不想做的。对于模拟,我们希望尽可能简单,因为我们希望它尽可能不影响测试中的组件。
Http
在测试过程中的另一个问题是它依赖于平台浏览器,这在测试环境中是不可用的。这并不意味着我们不能使用它。我们只需要使用 Angular 提供的帮助程序 class 进行测试。
我们介绍了模拟服务以测试组件,但如果您还想测试您的服务,您需要使用一些 Angular 测试助手 class 自己创建 Http
提供程序MockBackend
.
TestBed.configureTestingModule({
providers: [
{
provide: Http, useFactory: (backend, options) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
},
MockBackend,
BaseRequestOptions
]
});
有了 MockBackend
,我们可以订阅连接和模拟响应。有关完整示例,请参阅
另请参阅:
- Documentation for
Promise
,如果您不熟悉创建自己的 promise。
我正在尝试编写一个单元测试以确定 属性 在我的 angular 2 组件上填充 returns 承诺后的服务调用。
我的组件包含一个方法:
getListItems() {
this.employeeService.loadEmployees().then(res => {
this._employees = res['Employees'];
this.ref.markForCheck();
});
};
在服务上调用方法:
@Injectable()
export class EmployeeService {
constructor(
public http: Http
) { }
public loadEmployees(): Promise<any> {
return this.http.get('employees.json')
.map((res: Response) => res.json())
.toPromise();
}
}
从本地 json 文件中获取内容(代替创建远程端点)。这很好用,但我想在测试时用调用本地 json-server 的方法替换服务方法。
据我所知,在 Karma 测试 运行 时,我已经让 json-服务器正确旋转 up/down - 我可以使用 Postman 成功执行 GET 请求测试 运行ning.
因此我想用 mock 替换我的服务:
class MockEmployeeService {
headers: Headers;
constructor(private http: Http) {
this.headers = new Headers({ 'Content-Type': 'application/json' });
}
public loadEmployees() {
return this.http.get('http://localhost:3004/getEmployees',
{headers: this.headers, body: '' })
.map((res: Response) => res.json());
}
}
并且我已经按如下方式设置了单元测试:
describe('ListComponent', () => {
let fixture;
let component;
let employeeService;
beforeEach( async(() => {
TestBed.configureTestingModule({
imports: [
HttpModule
],
declarations: [
ListComponent
],
providers: [
{provide: EmployeeService, useClass: MockEmployeeService}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListComponent);
component = fixture.componentInstance;
employeeService = fixture.debugElement.injector
.get(EmployeeService);
});
it('should retrieve test values from json-server (async)',
async(() => {
fixture.detectChanges();
component.getListItems();
fixture.whenStable.then(() => {
expect(component._employees).toBeDefined();
});
}));
})
所以(我认为)我在应该调用服务的组件上调用方法,应该用 MockEmployeeService
替换。我收到以下 Karma 错误:
× should retrieve test values from json-server (async)
PhantomJS 2.1.1 (Windows 7 0.0.0)
Failed: Can't resolve all parameters for MockEmployeeService: (?).
在这一点上,我几乎处于我的知识范围内,我很难找到用于较新的、使用 TestBed 的测试的在线资源。有谁能看出这里有什么不对劲的地方吗?
如果您正在模拟该服务,则不应使用 Http
。只是 return 你自己的承诺,不与 Http
.
class MockEmployeeService {
public loadEmployees() {
return Promise.resolve({some:'object'});
}
}
使用 Http
服务,您将进行 XHR 调用,这在测试期间是您不想做的。对于模拟,我们希望尽可能简单,因为我们希望它尽可能不影响测试中的组件。
Http
在测试过程中的另一个问题是它依赖于平台浏览器,这在测试环境中是不可用的。这并不意味着我们不能使用它。我们只需要使用 Angular 提供的帮助程序 class 进行测试。
我们介绍了模拟服务以测试组件,但如果您还想测试您的服务,您需要使用一些 Angular 测试助手 class 自己创建 Http
提供程序MockBackend
.
TestBed.configureTestingModule({
providers: [
{
provide: Http, useFactory: (backend, options) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
},
MockBackend,
BaseRequestOptions
]
});
有了 MockBackend
,我们可以订阅连接和模拟响应。有关完整示例,请参阅
另请参阅:
- Documentation for
Promise
,如果您不熟悉创建自己的 promise。