Angular 具有模拟服务的单元测试组件-错误
我开始在Angular中测试组件和服务。我在pluralsight上观看了一门课程,并试图遵循以下观点: 但是,我对测试组件方法有一个问题。不幸的是,我找不到解决办法,所以决定向你寻求帮助 我的服务:Angular 具有模拟服务的单元测试组件-错误,angular,unit-testing,jasmine,mocking,spy,Angular,Unit Testing,Jasmine,Mocking,Spy,我开始在Angular中测试组件和服务。我在pluralsight上观看了一门课程,并试图遵循以下观点: 但是,我对测试组件方法有一个问题。不幸的是,我找不到解决办法,所以决定向你寻求帮助 我的服务: @Injectable() export class MyService { private config: AppConfig; constructor(private apiService: ApiService, private configService: Configuratio
@Injectable()
export class MyService {
private config: AppConfig;
constructor(private apiService: ApiService, private configService: ConfigurationService) {
this.config = configService.instant<AppConfig>();
}
public get(name: string, take: number = 10, skip: number = 0, params?:any): Observable<any> {
return this.apiService.post(`${this.config.baseUrl}/${name}/paginated?take=${take}&skip=${skip}`, params);
}
}
My.component.spec.ts测试文件:
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let mockService;
let ITEMS = [
{
"title": "test",
"id": "5e188d4f-5678-461b-8095-5dcffec0855a"
},
{
"title": "test2",
"id": "5e188d4f-1234-461b-8095-5dcffec0855a"
}
]
beforeEach(async(() => {
mockService = jasmine.createSpyObj(['get']);
TestBed.configureTestingModule({
imports: [NgxPaginationModule, RouterTestingModule],
declarations: [MyComponent],
providers: [
{ provide: MyService, useValue: mockService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// works fine
it('should create', () => {
expect(component).toBeTruthy();
});
// works fine
it('should NOT call updateItems method on initialization', () => {
component.ngOnInit();
let spy = spyOn(component, 'updateItems').and.callThrough();
expect(spy).not.toHaveBeenCalled();
});
// works fine
it('should call updateItems method on initialization', () => {
component.customerId = "1";
let spy = spyOn(component, 'updateItems').and.callFake(() => { return null });
component.ngOnInit();
expect(spy).toHaveBeenCalled();
});
// gives error
it('should update items', () => {
component.pagingInfo.currentPage = 1;
component.pagingInfo.itemsPerPage = 10;
component.customerId = "1";
mockService.get.and.returnValue(of(ITEMS));
component.updateItems();
expect(component.items).toBe(ITEMS);
});
});
description('MyComponent',()=>{
let组分:MyComponent;
let夹具:组件夹具;
让我们来服务;
让项目=[
{
“标题”:“测试”,
“id”:“5e188d4f-5678-461b-8095-5dcffec0855a”
},
{
“标题”:“测试2”,
“id”:“5e188d4f-1234-461b-8095-5dcffec0855a”
}
]
beforeach(异步(()=>{
mockService=jasmine.createSpyObj(['get']);
TestBed.configureTestingModule({
导入:[NgxPaginationModule,RouterTestingModule],
声明:[MyComponent],
供应商:[
{提供:MyService,使用值:mockService}
]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(MyComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
//很好
它('应该创建',()=>{
expect(component.toBeTruthy();
});
//很好
它('初始化时不应调用updateItems方法',()=>{
组件。ngOnInit();
让spy=spyOn(组件'updateItems')。和.callThrough();
期望(间谍).not.tohavebeincall();
});
//很好
它('应该在初始化时调用updateItems方法',()=>{
component.customerId=“1”;
让spy=spyOn(组件'updateItems')。和.callFake(()=>{returnnull});
组件。ngOnInit();
期望(间谍)。已被调用();
});
//出错
它('应该更新项目',()=>{
component.PaginInfo.currentPage=1;
component.pagininfo.itemsPerPage=10;
component.customerId=“1”;
mockService.get.and.returnValue(项的);
updateItems();
expect(组件项)。toBe(项);
});
});
3个最初的测试工作正常,但是对于最后更新的项目,我得到了错误:
预期未定义为[对象({“标题”:“测试”,“id”:“5e188d4f-5678-461b-8095-5dcffec0855a”},{“标题”:“测试2”,“id”:“5e188d4f-1234-461b-8095-5dcffec0855a”})]
如有任何提示,我将不胜感激;) 非常完整的问题,谢谢!这使我能够将所有这些都放在一个文件夹中,以确保我正确地发现了您所面临的问题。:) 在那次闪电战中,你可以看到测试现在都通过了。为了让它们通过,我只对您拥有的进行了一次更改,我更改了您从
mockService.get
返回的值,如下所示:
mockService.get.and.returnValue(of({entities: ITEMS, total: 2}));
原因是组件希望结果对象中有一个具有项值的“entities”键。注意——它还希望有一个“total”键,所以我也添加了这个键,尽管您没有测试它
另一件需要注意的事情,我在StackBlitz中做了更改以演示。虽然您的测试在编写时都会通过,但您可能没有意识到,fixture.detectChanges()
实际上执行了ngOnInit()
——这在以前的测试中让我大吃一惊。为了说明这一点,我修改了在一个规范中专门调用component.ngOnInit()
的位置以及在此规范中调用component.updateItems()
的位置,并将它们替换为fixture.detectChanges()
。当然,这两种方法都可以很好地工作,但我指出了这一点,因为在一些测试中,您需要在调用ngOnInit()
获取有效数据之前设置mock,并将fixture.detectChanges()
放在beforeach()
中,所有规范都意味着每次调用规范之前都会调用它
我希望这能有所帮助。天哪!非常感谢你,你解决了我数小时痛苦的思考、尝试和错误!
mockService.get.and.returnValue(of({entities: ITEMS, total: 2}));