使用 jasmine angular2 注入私人服务的单元测试
Unit testing with private service injected using jasmine angular2
我在尝试对 angular 服务进行单元测试时遇到问题。我想验证此服务是否正确调用注入其中的另一个服务。
假设我有这个注入 ServiceInjected 的 ServiceToTest:
服务测试.service.ts
@Injectable()
export class ServiceToTest {
constructor(private _si: ServiceInjected) {}
public init() {
this._si.configure();
}
}
ServiceInjected。service.ts
@Injectable()
export class ServiceInjected {
constructor() {}
public configure() {
/*Some actions*/
}
}
有了这些服务,现在我编写我的单元测试:
const serviceInjectedStub = {
configure(): void {}
}
describe('ServiceToTest service Test', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
});
it('should be initialize the service injected', inject([ServiceToTest],
(tService: ServiceToTest) => {
spyOn(serviceInjectedStub, 'configure');
tService.init();
expect(serviceInjectedStub.configure).toHaveBeenCalled();
}));
我原以为我的测试是阳性的,但是我收到以下错误:
预期已调用间谍配置。
另一方面,如果我以这种方式设置注入服务 public 它工作正常:
private _si: ServiceInjected by public si: ServiceInjected
使用这个:
spyOn(serviceInjectedStub, 'configure').and.returnValue(配置); // 配置是一个 mock
您不会监视与您的 TestBed 相关的服务。从您的测试台获取服务
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
injectedService = TestBed.get(ServiceInjected);
});
并对其进行测试
spyOn(injectedService, 'configure').and.returnValue(/* return same data type here */);
// ...
expect(injectedService.configure).toHaveBeenCalled();
或者您可以使用 jasmine.createSpyObj
并为其提供 useValue
,如下所示:
describe('YourComponent', () => {
let serviceInjectedSpy: jasmine.SpyObj<ServiceInjected>;
beforeEach(async(() => {
// notice here
serviceInjectedSpy = jasmine.createSpyObj('ServiceInjected', ['configure']);
TestBed.configureTestingModule({
declarations: [YourComponent],
providers: [
{provide: ServiceInjected, useValue: serviceInjectedSpy}
],
imports: [
...
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
});
});
it('should assert my test', () => {
serviceInjectedSpy.configure.and.returnValue(/* what you want */);
component.init();
expect(serviceInjectedSpy.configure).toHaveBeenCalled();
});
});
从 Angular 9 你应该使用 TestBed.inject
;那么您就不需要在提供商列表中添加该服务了。
let injectedService: ServiceInjected;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest]
});
injectedService = TestBed.inject(ServiceInjected);
});
然后监视它
// if you want to ignore the call
spyOn(injectedService, 'configure').and.callThrough();
// if you need to set stuff up
spyOn(injectedService, 'configure').and.callFake(async () => {/* some fake stuff */});
并进行检查
expect(injectedService.configure).toHaveBeenCalled();
// ...
我在尝试对 angular 服务进行单元测试时遇到问题。我想验证此服务是否正确调用注入其中的另一个服务。
假设我有这个注入 ServiceInjected 的 ServiceToTest:
服务测试.service.ts
@Injectable()
export class ServiceToTest {
constructor(private _si: ServiceInjected) {}
public init() {
this._si.configure();
}
}
ServiceInjected。service.ts
@Injectable()
export class ServiceInjected {
constructor() {}
public configure() {
/*Some actions*/
}
}
有了这些服务,现在我编写我的单元测试:
const serviceInjectedStub = {
configure(): void {}
}
describe('ServiceToTest service Test', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
});
it('should be initialize the service injected', inject([ServiceToTest],
(tService: ServiceToTest) => {
spyOn(serviceInjectedStub, 'configure');
tService.init();
expect(serviceInjectedStub.configure).toHaveBeenCalled();
}));
我原以为我的测试是阳性的,但是我收到以下错误:
预期已调用间谍配置。
另一方面,如果我以这种方式设置注入服务 public 它工作正常:
private _si: ServiceInjected by public si: ServiceInjected
使用这个:
spyOn(serviceInjectedStub, 'configure').and.returnValue(配置); // 配置是一个 mock
您不会监视与您的 TestBed 相关的服务。从您的测试台获取服务
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest ,
{ provide: ServiceInjected, useValue: serviceInjectedStub }]
});
injectedService = TestBed.get(ServiceInjected);
});
并对其进行测试
spyOn(injectedService, 'configure').and.returnValue(/* return same data type here */);
// ...
expect(injectedService.configure).toHaveBeenCalled();
或者您可以使用 jasmine.createSpyObj
并为其提供 useValue
,如下所示:
describe('YourComponent', () => {
let serviceInjectedSpy: jasmine.SpyObj<ServiceInjected>;
beforeEach(async(() => {
// notice here
serviceInjectedSpy = jasmine.createSpyObj('ServiceInjected', ['configure']);
TestBed.configureTestingModule({
declarations: [YourComponent],
providers: [
{provide: ServiceInjected, useValue: serviceInjectedSpy}
],
imports: [
...
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
});
});
it('should assert my test', () => {
serviceInjectedSpy.configure.and.returnValue(/* what you want */);
component.init();
expect(serviceInjectedSpy.configure).toHaveBeenCalled();
});
});
从 Angular 9 你应该使用 TestBed.inject
;那么您就不需要在提供商列表中添加该服务了。
let injectedService: ServiceInjected;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ServiceToTest]
});
injectedService = TestBed.inject(ServiceInjected);
});
然后监视它
// if you want to ignore the call
spyOn(injectedService, 'configure').and.callThrough();
// if you need to set stuff up
spyOn(injectedService, 'configure').and.callFake(async () => {/* some fake stuff */});
并进行检查
expect(injectedService.configure).toHaveBeenCalled();
// ...