gpt4 book ai didi

javascript - 在使用 async 和声明性方法使用 observable 测试 Angular 组件时,获取 TypeError 管道不是函数

转载 作者:行者123 更新时间:2023-11-30 13:50:23 25 4
gpt4 key购买 nike

When run the tests i am getting i am getting the "TypeError: this.dashboardService.serviceAgents$.pipe is not a function" error.

  • ServiceDashboard 页面代码如下:

import { Component } from '@angular/core';
import { ServiceDashboardService } from '../services/service-dashboard.service';
import { tap } from 'rxjs/operators';
import { ServiceAgent } from '../interfaces/service-agent';
@Component({
selector: 'app-service-dashboard',
templateUrl: './service-dashboard.page.html',
styleUrls: ['./service-dashboard.page.css'],
})
export class ServiceDashboardPage {
serviceAgentSlideOptions: any = {
slidesPerView: 4
};
serviceAgents$ = this.dashboardService.serviceAgents$
.pipe(
tap(serviceAgents => {
this.serviceAgentSlideOptions.slidesPerView = serviceAgents.length < 4 ? serviceAgents.length : 4;
})
);
constructor(private dashboardService: ServiceDashboardService) { }
}
  • 以下是 ServiceDashboardPage 的单元测试代码。
      import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ServiceDashboardPage } from './service-dashboard.page';
import { ServiceDashboardService } from '../services/service-dashboard.service';
import { ServiceAgent } from '../interfaces/service-agent';
import { of } from 'rxjs';
describe('ServiceDashboardPage', () => {
let component: ServiceDashboardPage;
let fixture: ComponentFixture<ServiceDashboardPage>;
let serviceDashboardServiceSpy: ServiceDashboardService;
beforeEach(async(() => {
serviceDashboardServiceSpy = jasmine.createSpyObj('ServiceDashboardService',
['serviceAgents$']);
TestBed.configureTestingModule({
declarations: [ServiceDashboardPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: ServiceDashboardService, useValue: serviceDashboardServiceSpy }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ServiceDashboardPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', async(() => {
(serviceDashboardServiceSpy.serviceAgents$ as unknown as
jasmine.Spy).and.returnValue(of([] as ServiceAgent[]));
expect(component).toBeTruthy();
}));
});

最佳答案

您编写的代码存在许多问题。正如上面评论中指出的那样,您显然希望服务中有一个 Observable,但是命令:

serviceDashboardServiceSpy = jasmine.createSpyObj('ServiceDashboardService', ['serviceAgents$']);

将创建 serviceAgents$ 作为一个函数,而不是作为一个 Observable。

但是仅仅更改它不会使您的代码可测试,因为您将想要更改该 Observable 返回的值并进行测试以查看您的组件是否对这些更改做出正确的 react 。为此,您需要重构代码。重构的原因是因为您通过立即定义在组件中设置 Observable 的方式意味着很难更改值和轻松测试。然而,只需将赋值移至 ngOnInit() 即可使它更易于测试。

然后,您需要将 fixture.detectChanges() 移出 beforeEach() 并移入规范本身(it() 功能)。这样做的原因是因为 fixture.detectChanges() 将执行我们刚刚设置的 ngOnInit(),我们希望更仔细地控制它何时被调用。

最后,您需要设置一些东西来模拟您的服务类 - 您试图使用 serviceDashboardServiceSpy 对象来这样做,但在这种情况下我更喜欢使用模拟类而不是 spy 目的。这样做的原因是因为您在实际服务类中将 serviceAgents$ 定义为 PROPERTY 而不是函数。这使得测试变得更加棘手,在我看来,设置模拟类而不是 spy 对象会使测试变得更容易一些。

考虑到所有这些因素,我设置了这个 StackBlitz以显示您的测试通过。

我还添加了一些测试来展示更改服务 Observable 中的值如何更改组件中的关联值。

这是来自 StackBlitz 的 .spec:

class MockServiceDashboardService {
get serviceAgents$() {
return of({length: 2});
}
}

describe('ServiceDashboardPage', () => {
let component: ServiceDashboardPage;
let fixture: ComponentFixture<ServiceDashboardPage>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ServiceDashboardPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: ServiceDashboardService, useClass: MockServiceDashboardService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ServiceDashboardPage);
component = fixture.componentInstance;
});
it('should create', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
it('should have length of 2', () => {
fixture.detectChanges();
expect(component.serviceAgentSlideOptions.slidesPerView).toEqual(2);
});
it('should have a length of 3', () => {
let dService = TestBed.get(ServiceDashboardService);
spyOnProperty(dService, 'serviceAgents$').and.returnValue(of({length: 3}))
fixture.detectChanges();
expect(component.serviceAgentSlideOptions.slidesPerView).toEqual(3);
});
});

关于javascript - 在使用 async 和声明性方法使用 observable 测试 Angular 组件时,获取 TypeError 管道不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58375178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com