Javascript 当服务在组件的根目录中提供时,如何监视服务的方法
我正在使用karma jasmine为一个角度组件编写单元测试。我在ProfileComponent和ProfileService中使用了提供程序 profile.component.tsJavascript 当服务在组件的根目录中提供时,如何监视服务的方法,javascript,angular,typescript,jasmine,karma-jasmine,Javascript,Angular,Typescript,Jasmine,Karma Jasmine,我正在使用karma jasmine为一个角度组件编写单元测试。我在ProfileComponent和ProfileService中使用了提供程序 profile.component.ts beforeEach(async(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingM
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule],
declarations: [ProfileComponent],
providers: [ {provide: ProfileService , useClass: ProfileServiceStub } ], // <-- useclass here
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
@组件({
选择器:“应用程序配置文件”,
templateUrl:'./profile.component.html',
样式URL:['./profile.component.scss'],
提供者:[配置文件服务]
})
导出类ProfileComponent实现OnInit{
公共数据;
构造函数(私有profileService:profileService){}
恩戈尼尼特(){
等待这个.profileService.login();
this.profileService.getData('A').subscribe((结果)=>{
这个数据=结果;
});
}
}
profile.service.ts
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule],
declarations: [ProfileComponent],
providers: [ {provide: ProfileService , useClass: ProfileServiceStub } ], // <-- useclass here
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
@Injectable()
导出类配置文件服务{
私有baseUrl:string;
构造函数(专用http:HttpClient){
此.baseUrl=https://localhost:4002';
}
公共异步登录(){
const loginUrl=`${this.baseUrl}/api/Login`;
返回this.http.post(loginUrl,{},{headers}).toPromise();
}
getData(id:字符串){
consturl=`${this.baseUrl}/api/GetData/${id}`;
返回this.http.get(url,{headers});
}
}
配置文件组件规范ts
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule],
declarations: [ProfileComponent],
providers: [ {provide: ProfileService , useClass: ProfileServiceStub } ], // <-- useclass here
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
const data=['A','B','C'];
描述('Client.App.ProfileComponent',()=>{
let组件:ProfileComponent;
let fixture:ComponentFixture;
让profileService:profileService;
让我们来分析数据;
beforeach(异步(()=>{
TestBed.configureTestingModule({
导入:[HttpClientTestingModule,ReactiveFormsModule,RouterTestingModule],
声明:[ProfileComponent],
提供者:[配置文件服务],
架构:[无错误\u架构]
}).compileComponents();
}));
beforeach(fakeAsync(()=>{
profileData=新主题();
profileService=TestBed.inject(profileService);
spyOn(profileService,'login')。和.returnValue({});
spyOn(profileService,'getData')。和.returnValue(profileData);
fixture=TestBed.createComponent(ProfileComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
}));
它('应创建组件',()=>{
profileData.next(数据);
fixture.detectChanges();
expect(component.toBeDefined();
});
});
我添加了一个调试器,并检查其登录是否失败。因此,我有两个问题:
配置文件组件中使用了提供者
,我是否可以在Profile.Component.spec.ts
文件中插入ProfileService
,因为它将创建同一服务的两个实例spyOn(profileService,'login').and.returnValue({});
请在这方面帮助我。1。)我认为您所拥有的一切都很好,将ProfileService
放入测试床中的provider
数组中。configureTestingModule
很好,当创建组件时,它知道如何制作它。每次创建组件时,它都将是一个单独的提供程序,但无论是在组件中提供提供程序,还是全局提供提供程序,都是如此,因为测试构造和销毁(在每个…TestBed.configureTestingModule…之前)
2.)尝试'spyOn(profileService,'login')。和.returnValue(Promise.resolve({}))
旁注:
ngonit
需要一个异步修饰符才能使用wait。首先,您需要提供一个模拟,而不是提供实际的服务实例。之后,您需要提供该服务方法的假实现。请在下面找到所需的更改和内联注释
const data =['A','B','C'];
describe('Client.App.ProfileComponent', () => {
let component: ProfileComponent;
let fixture: ComponentFixture<ProfileComponent>;
let profileService: jasmine.SpyObj<ProfileService>;
beforeEach(async(() => {
// create a spied service and use it inside providers array
profileService = jasmine.createSpyObj('ProfileService', ['login', 'getData']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule],
declarations: [ProfileComponent],
providers: [ { provide: ProfileService, useValue: profileService ],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
// provide fake implementation to service methods
profileService.login.and.returnValue(Promise.resolve('success'));
profileService.getData.and.returnValue(of(data)); // of is rxjs operators- import
fixture = TestBed.createComponent(ProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('shall create the component', () => {
expect(component).toBeDefined();
});
});
const data=['A','B','C'];
描述('Client.App.ProfileComponent',()=>{
let组件:ProfileComponent;
let夹具:组件夹具;
让我们为您服务:jasmine.SpyObj;
beforeach(异步(()=>{
//创建一个间谍服务并在提供者数组中使用它
profileService=jasmine.createSpyObj('profileService',['login','getData']);
TestBed.configureTestingModule({
导入:[HttpClientTestingModule,ReactiveFormsModule,RouterTestingModule],
声明:[ProfileComponent],
提供程序:[{provide:ProfileService,useValue:ProfileService],
架构:[无错误\u架构]
}).compileComponents();
//为服务方法提供假实现
profileService.login.and.returnValue(Promise.resolve('success');
profileService.getData.and.returnValue(of(data));//of是rxjs操作符-导入
fixture=TestBed.createComponent(ProfileComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
}));
它('应创建组件',()=>{
expect(component.toBeDefined();
});
});
存根
,用useClass>替换对实际ProfileService
的依赖关系
export class ProfileServiceStub {
getData(id: string) {
return of({some_obj: "value"})
}
}
和规范ts中的
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ReactiveFormsModule, RouterTestingModule],
declarations: [ProfileComponent],
providers: [ {provide: ProfileService , useClass: ProfileServiceStub } ], // <-- useclass here
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
我强烈建议您阅读其登录失败,我无法继续。如何在规范文件中的ngOnInit上添加异步装饰器…?将async
放在它前面,如:async ngOnInit(){…}
。