Sup*_*miu 17 karma-jasmine angular2-services angular2-injection angular2-testing angular
我创建了一个ApiService类来处理我们的自定义API查询,同时使用我们自己的序列化程序+其他功能.
ApiService的构造函数签名是:
constructor(metaManager: MetaManager, connector: ApiConnectorService, eventDispatcher: EventDispatcher);
Run Code Online (Sandbox Code Playgroud)
MetaManager 是一种处理api的metadatas的可注射服务.ApiConnectorService是一个包装的服务,Http用于添加我们的自定义标题和签名系统.EventDispatcher 基本上是Symfony的事件调度系统,在打字稿中.当我测试时ApiService,我做了一个初始化beforeEach:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [
HttpModule
],
providers: [
ApiConnectorService,
ApiService,
MetaManager,
EventDispatcher,
OFF_LOGGER_PROVIDERS
]
});
}));
Run Code Online (Sandbox Code Playgroud)
它工作正常.
然后,添加我的第二个规范文件,该文件是ApiConnectorService,与此beforeEach:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [HttpModule],
providers: [
ApiConnectorService,
OFF_LOGGER_PROVIDERS,
AuthenticationManager,
EventDispatcher
]
});
}));
Run Code Online (Sandbox Code Playgroud)
并且所有测试都因此错误而失败:
错误:无法解析ApiService的所有参数:(MetaManager,?,EventDispatcher).
api-connector-service.spec.ts(ApiConnectorService的spec文件),ApiService测试将成功.api-service.spec.ts(ApiService的spec文件),ApiConnectorService测试将成功.为什么我有这个错误?看起来我的两个文件之间的上下文存在冲突,我不知道为什么以及如何解决这个问题.
Mik*_*ple 20
如果有人来到这里并且您正在使用 Jest 来测试您的 Angular 应用程序(希望我们是一个不断增长的少数人),如果您没有发出装饰器,您将遇到此错误。您需要更新您的tsconfig.spec.json文件,使其看起来像:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"emitDecoratorMetadata": true,
"outDir": "../../out-tsc/spec",
"types": [
"jest",
"node"
]
},
"files": [
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*tha 16
这是因为在测试环境中Http无法从服务中解析服务HttpModule.它取决于平台浏览器.在测试过程中,您甚至不应该尝试进行XHR调用.
出于这个原因,Angular提供了一个MockBackend供Http服务使用的服务.我们使用这个模拟后端在我们的测试中订阅连接,并且我们可以在建立每个连接时模拟响应.
这是一个可以解决的简短完整示例
import { Injectable } from '@angular/core';
import { async, inject, TestBed } from '@angular/core/testing';
import { MockBackend, MockConnection } from '@angular/http/testing';
import {
Http, HttpModule, XHRBackend, ResponseOptions,
Response, BaseRequestOptions
} from '@angular/http';
@Injectable()
class SomeService {
constructor(private _http: Http) {}
getSomething(url) {
return this._http.get(url).map(res => res.text());
}
}
describe('service: SomeService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: Http, useFactory: (backend, options) => {
return new Http(backend, options);
},
deps: [MockBackend, BaseRequestOptions]
},
MockBackend,
BaseRequestOptions,
SomeService
]
});
});
it('should get value',
async(inject([SomeService, MockBackend],
(service: SomeService, backend: MockBackend) => {
backend.connections.subscribe((conn: MockConnection) => {
const options: ResponseOptions = new ResponseOptions({body: 'hello'});
conn.mockRespond(new Response(options));
});
service.getSomething('http://dummy.com').subscribe(res => {
console.log('subcription called');
expect(res).toEqual('hello');
});
})));
});Run Code Online (Sandbox Code Playgroud)
在选择的答案中并没有真正解决问题,这实际上只是编写测试的建议,而在注释中,您必须点击链接并在此处搜索。由于我又遇到了同样的错误,因此我将在此处添加两个解决方案。
如果您有一个桶(index.ts或多个导出文件),如下所示:
export * from 'my.component' // using my.service via DI
export * from 'my.service'
Run Code Online (Sandbox Code Playgroud)
然后您可能会收到类似的错误EXCEPTION: Can't resolve all parameters for MyComponent: (?)。
要修复它,您必须在组件之前导出服务:
export * from 'my.service'
export * from 'my.component' // using my.service via DI
Run Code Online (Sandbox Code Playgroud)
由于circular dependency导致undefined服务导入的相同错误可能发生。console.log(YourService)导入后进行检查(在测试文件中-发生问题的位置)。如果未定义,您可能已经制作了一个index.ts文件(桶式),用于导出服务和使用该文件的文件(组件/效果/无论您要测试的内容)-通过从导出了索引的文件中导入服务(使其变成完整圆圈)。
找到该文件,然后直接从your.service.ts文件而不是从索引导入所需的服务。
| 归档时间: |
|
| 查看次数: |
16960 次 |
| 最近记录: |