Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 具有模拟服务的单元测试组件-错误_Angular_Unit Testing_Jasmine_Mocking_Spy - Fatal编程技术网

Angular 具有模拟服务的单元测试组件-错误

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

我开始在Angular中测试组件和服务。我在pluralsight上观看了一门课程,并试图遵循以下观点: 但是,我对测试组件方法有一个问题。不幸的是,我找不到解决办法,所以决定向你寻求帮助

我的服务:

@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}));