Angular 8 karma 测试服务而不在构造函数中注入所有服务
Angular 8 karma test a service without injecting all service in the constructor
我是 Angular 使用 Karma 进行测试的新手,我不了解如何正确测试服务。
假设我有必须测试的服务:
@Injectable()
export class MyService {
constructor(private httpService: HttpService) { }
//methods to test
}
这是我的测试class:
describe('MyService', () => {
let service: MyService;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [MyService],
}).compileComponents();
service = TestBed.get(MyService);
}));
});
当我 运行 ng 测试时,它给出了错误 NullInjectorError: No provider for HttpService!
。
所以我在测试 class 中将 HttpService 添加到提供程序数组中,这样:
describe('MyService', () => {
let service: MyService;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [MyService, HttpService],
}).compileComponents();
service = TestBed.get(MyService);
}));
});
HttpService 是这样的:
@Injectable()
export class HttpService{
constructor(private httpService: HttpClient) { }
}
所以现在我收到错误 NullInjectorError: No provider for HttpClient!
。 (HttpClient 来自@angular/common/http).
如果我在 test class 中将 HttpClient 添加到 providers 数组,那么 HttpClient 构造函数中的所有 services/class 都会出现相同的错误,依此类推。在不必添加每个提供商的情况下启动服务的正确方法是什么,从而导致潜在的无限提供商?
在您的 Testbed 配置中,导入 HttpClientTestingModule
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [MyService, HttpService],
}).compileComponents();
service = TestBed.get(MyService);
}));
你也可以考虑
将 TestBed.get(MyService);
更改为 TestBed.inject(MyService);
,因为 TestBed.get(...)
已弃用 What's the difference between TestBed.get and new Service(...dependencies)
将 async
更改为 waitForAsync
,因为 async
已弃用
您应该使用 HttpClientTestingModule
并使用 HttpTestingController
和 flush
方法模拟数据。这是 Angular 11 和 jasmine 3.6.0 关于我如何测试服务的示例。希望对你有帮助:
// Dependencies
import { TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
// Assets
import { ExampleService } from './api/example.service';
describe('*[Example Service]: -----------------------------------------', () => {
let httpTestingController: HttpTestingController;
let service: ExampleService;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
]
}).compileComponents();
httpTestingController = TestBed.inject(HttpTestingController);
service = TestBed.inject(ExampleService);
}));
it('1). should get data from GET service', waitForAsync( () => {
// Arrange
const expectedData: string[] = ['data1', 'data2'];
let apiError, apiData;
// Action
service.getData().subscribe(response => {
apiData = response;
}, error => {
apiError = error;
});
const request = httpTestingController.expectOne(`http://localhost:3000/example`);
request.flush(expectedData);
// Assert
expect(apiData.length).toEqual(2);
expect(apiError).toBeUndefined();
}));
});
我是 Angular 使用 Karma 进行测试的新手,我不了解如何正确测试服务。 假设我有必须测试的服务:
@Injectable()
export class MyService {
constructor(private httpService: HttpService) { }
//methods to test
}
这是我的测试class:
describe('MyService', () => {
let service: MyService;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [MyService],
}).compileComponents();
service = TestBed.get(MyService);
}));
});
当我 运行 ng 测试时,它给出了错误 NullInjectorError: No provider for HttpService!
。
所以我在测试 class 中将 HttpService 添加到提供程序数组中,这样:
describe('MyService', () => {
let service: MyService;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [MyService, HttpService],
}).compileComponents();
service = TestBed.get(MyService);
}));
});
HttpService 是这样的:
@Injectable()
export class HttpService{
constructor(private httpService: HttpClient) { }
}
所以现在我收到错误 NullInjectorError: No provider for HttpClient!
。 (HttpClient 来自@angular/common/http).
如果我在 test class 中将 HttpClient 添加到 providers 数组,那么 HttpClient 构造函数中的所有 services/class 都会出现相同的错误,依此类推。在不必添加每个提供商的情况下启动服务的正确方法是什么,从而导致潜在的无限提供商?
在您的 Testbed 配置中,导入 HttpClientTestingModule
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [MyService, HttpService],
}).compileComponents();
service = TestBed.get(MyService);
}));
你也可以考虑
将
TestBed.get(MyService);
更改为TestBed.inject(MyService);
,因为TestBed.get(...)
已弃用 What's the difference between TestBed.get and new Service(...dependencies)将
async
更改为waitForAsync
,因为async
已弃用
您应该使用 HttpClientTestingModule
并使用 HttpTestingController
和 flush
方法模拟数据。这是 Angular 11 和 jasmine 3.6.0 关于我如何测试服务的示例。希望对你有帮助:
// Dependencies
import { TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
// Assets
import { ExampleService } from './api/example.service';
describe('*[Example Service]: -----------------------------------------', () => {
let httpTestingController: HttpTestingController;
let service: ExampleService;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
]
}).compileComponents();
httpTestingController = TestBed.inject(HttpTestingController);
service = TestBed.inject(ExampleService);
}));
it('1). should get data from GET service', waitForAsync( () => {
// Arrange
const expectedData: string[] = ['data1', 'data2'];
let apiError, apiData;
// Action
service.getData().subscribe(response => {
apiData = response;
}, error => {
apiError = error;
});
const request = httpTestingController.expectOne(`http://localhost:3000/example`);
request.flush(expectedData);
// Assert
expect(apiData.length).toEqual(2);
expect(apiError).toBeUndefined();
}));
});