Angular 无法读取未定义错误的属性订阅

时间:2021-03-04 12:20:14

标签: angular typescript unit-testing karma-jasmine

我得到这个奇怪的无法读取未定义错误的订阅,奇怪的是当它独立运行时不会出现一些东西,但在不使用集中测试的情况下运行时几乎总是出现

<块引用>

错误现在显示在行 this.accessGroupService.getAccessGroup(accessGroupId).subscribe( (json) 在 view-access-group.component.ts 文件

这是测试文件

view-access-group.component.spec.ts

describe("ViewAccessGroupComponent", () => {
  let component: ViewAccessGroupComponent;
  let fixture: ComponentFixture<ViewAccessGroupComponent>;
  let notifyServiceSpy: jasmine.SpyObj<NotificationService>;
  let accessGroupSpy: jasmine.SpyObj<AccessGroupService>;
  let route:ActivatedRoute;

  let activatedRouteMock = {
    params: of({ id: 1 })
  }
  

let g1: AccessGroup = {
    id: 1,
    active: true,
    display_name: '',
    description: '',
    access_group_features: [],
    toJSON: null
  }

  beforeEach(async(() => {
    const notifyServiceSpyObj = jasmine.createSpyObj("NotificationService", [
      "show",
    ]);
    const accessGroupServiceSpyObj = jasmine.createSpyObj(
      "AccessGroupService",[
        "getAccessGroup"
      ]
    );

    TestBed.configureTestingModule({
      imports: [
        ConfigurationModule,
        HttpClientTestingModule,
        RouterTestingModule,
      ],
      providers: [
        TranslateService,
        TranslateStore,
        Globals,
        { provide: NotificationService, useValue: notifyServiceSpyObj },
        { provide: AccessGroupService, useValue: accessGroupServiceSpyObj },
        {provide:ActivatedRoute,useValue:activatedRouteMock}
      ],
    }).compileComponents();
    notifyServiceSpy = TestBed.get(NotificationService);
    accessGroupSpy=TestBed.get(AccessGroupService);
    route=TestBed.get(ActivatedRoute)
  }));

  afterEach(()=>{
    fixture.destroy();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ViewAccessGroupComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it("should create", () => {
    expect(component).toBeTruthy();
  });

  it("#getAccessGroup should show error message if API fails ", () => {

    accessGroupSpy.getAccessGroup.and.returnValue(throwError({error:{message:"error"}}))
    
    component.getAccessGroup(1);

    expect(notifyServiceSpy.show).toHaveBeenCalledWith("error", {
      position: "top",
      duration: "3000",
      type: "error",
    });
  });

  it('when params has id', () => {

    accessGroupSpy.getAccessGroup.and.returnValue(of(g1))

    TestBed.createComponent(ViewAccessGroupComponent)

    expect(component.accessGroupId).toBe(1)
  })
});

这是主要的打字稿文件:

view-access-group.component.ts

@Component({
  selector: "batavia-view-access-group",
  templateUrl: "./view-access-group.component.html",
  styleUrls: ["./view-access-group.component.scss"],
})
export class ViewAccessGroupComponent implements OnInit {
  accessGroup: AccessGroup = new AccessGroup();
  accessGroupId: number;
  user: User;
  isLoading = false;
  accessGroupFeatures: AccessGroupFeature[];

  constructor(
    private accessGroupService: AccessGroupService,
    private activatedRoute: ActivatedRoute,
    private globals: Globals,
    private _notify: NotificationService,
    private translate: TranslateService
  ) {
    this.activatedRoute.params.subscribe((params: Params) => {
      if (params.id) {
        this.accessGroupId = params.id;
        this.getAccessGroup(params.id);
      }
    });

    this.globals.userObservable.subscribe((user) => (this.user = user));
  }

  ngOnInit() {}

  getAccessGroup(accessGroupId: number) {
    this.isLoading = true;
    this.accessGroupService.getAccessGroup(accessGroupId).subscribe(
      (json) => {
        this.isLoading = false;
        this.accessGroup = json;
      },
      (error) => {
        this.isLoading = false;
        const errMsg = this.translate.instant(
          "ACCESS_GROUPS.ERROR_FETCHING_ROLES"
        );
        this._notify.show(
          error.error && error.error.message ? error.error.message : errMsg,
          {
            position: "top",
            duration: "3000",
            type: "error",
          }
        );
      }
    );
  }
}

我不知道为什么会出现此错误。我尝试了各种网站上提供的许多内容,例如添加 afterEach 循环。

谁能指出为什么我的代码出错

1 个答案:

答案 0 :(得分:0)

在您到达测试用例之前调用您的间谍:

beforeEach(() => {
    fixture = TestBed.createComponent(ViewAccessGroupComponent);  // HERE, the constructor is called
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

您可以将订阅移动到 ngOnInit 中,然后在调用 fixture.detectChanges() 时订阅将完成,因此您可以将该调用移动到设置间谍结果的下方:

  it("#getAccessGroup should show error message if API fails ", () => {

    accessGroupSpy.getAccessGroup.and.returnValue(throwError({error:{message:"error"}}))
    
    fixture.detectChanges(); // HERE instead of in beforeEach