首页 > 解决方案 > 如何以角度模拟服务类的属性(Jasmine/Karma)

问题描述

我正在尝试从我的服务中模拟currentOrganizationMessageSource但收到以下错误:

this.OrganizationService.currentOrganizationMessageSource.subscribe 不是函数

我尝试使用 spyOnProperty,但我得到currentOrganizationMessageSource is not a property

班级:

export class OrganizationEditComponent implements OnInit {

  feedback: any = {};
  appOrgs: OrganizationDataModel;
  organizationLocationTableTitle: string;


  constructor(
    public route: ActivatedRoute,
    private router: Router,
    private orgService: OrganizationService) {
  }


  ngOnInit() {
    this.loadOrganisation();
  }

  private loadOrganisation()
  {
    this.orgService.currentOrganizationMessageSource.subscribe(
      org => this.appOrgs = org);
      this
      .route
      .params
      .pipe(
        map(p => p.id),
        switchMap(id => {
          if (id === 'new') { return of(this.appOrgs); }
          if (id != null) {
            return this.orgService.findByOrganizationsId(id);
          }
        })
      )
      .subscribe(orgs => {
          this.orgService.changeMessage(orgs);
          this.appOrgs = orgs;
          this.feedback = {};
        },
        err => {
          this.feedback = {type: 'warning', message:'Error'};
        }
      );
  }

服务:

export class OrganizationService {

  private OrganizationMessageSource = new BehaviorSubject( new OrganizationDataModel());
  currentOrganizationMessageSource = this.OrganizationMessageSource.asObservable();


  changeMessage(appOrganization: appOrganizationDataModel) {
    this.appOrganizationMessageSource.next(appOrganization);
  }
}

测试规格类:

fdescribe('OrganizationEditComponent', () => {
  let component: OrganizationEditComponent;
  let fixture: ComponentFixture<OrganizationEditComponent>;
  let activatedRoutes: any = {};


  beforeEach(async(async () => {
    const OrganizationService: OrganizationService = jasmine.createSpyObj('OrganizationService', ['currentOrganizationMessageSource']);
    await TestBed.configureTestingModule({
      declarations: [ OrganizationEditComponent ],
      providers: [
        { provide: ActivatedRoute, useValue: activatedRoutes },
        { provide: Router, useValue: {url: ''}},
        { provide: OrganizationService, useValue: OrganizationService },
      ],      
      imports: [ FormsModule ] ,
      schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
    })
    .compileComponents();
    // component.ngOnInit();
    fixture = TestBed.createComponent(OrganizationEditComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  function givenServicesAreMocked() {
    const spy = TestBed.get(OrganizationService);
    // let mockService = jasmine.createSpyObj(OrganizationService, ['currentOrganizationMessageSource']);
    // mockService.currentOrganizationMessageSource.and.returnValue('');
    // spyOnProperty(OrganizationService, "OrganizationMessageSource").and.returnValue([]);
    // OrganizationService.currentOrganizationMessageSource = () => {
    //   return [];
    // };
  }
});

标签: angularjasmineangular6karma-jasminespy

解决方案


你有正确的想法,但你不能用 来模拟属性createSpyObj,只能用方法来模拟。

import { of } from 'rxjs';
....
// the 2nd argument is for public methods, not properties
    const OrganizationService: OrganizationService = jasmine.createSpyObj('OrganizationService', ['changeMessage']);
// attach currentOrganizationMesageSource as a property to OrganizationService and mock the value
OrganizationService.currentOrganizationMessageSource = of(/* Mock the value here */);
// keep everything else the same

这应该会奏效。

您还需要正确地模拟ActivatedRouteRouter。对于路由器,只需添加RouterTestingModuleimports阵列。它由 Angular 提供,有助于测试注入路由器的组件/服务。


推荐阅读