【问题标题】:How to Mock History.state for writing unit tests in angular如何模拟 History.state 以使用 Angular 编写单元测试
【发布时间】:2019-11-05 13:10:27
【问题描述】:

我正在为我的组件编写单元测试,但在创建组件实例时遇到问题并显示以下错误,

TypeError: Cannot read property 'patientId' of null 

我尝试过模拟所有的供应商,包括路由器和活动路由器 我的 component.ts 是

export class PatientInsurancePlanSearchComponent implements OnInit {

  private patientId: number = -1;
  public selectedOrganizationInsurance: OrganizationInsurance;
  public organizationInsurancePlans$: Observable<OrganizationInsurancePlan[]>;

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private biilingHttpService: BillingHttpService
  ) {
    this.selectedOrganizationInsurance = new OrganizationInsurance();
  }

  ngOnInit() {
    this.patientId = history.state.patientId as number;
    this.selectedOrganizationInsurance = history.state.selectedOrganizationInsurance as OrganizationInsurance;
    this.organizationInsurancePlans$ = this.biilingHttpService.getOrganizationInsurancePlans(this.selectedOrganizationInsurance.id);
  }

spec.ts

class FakeInsurancePlanSearchComponent {
  @Input() public organizationInsurancePlans: OrganizationInsurancePlan[] = [];
  @Input() public selectedOrganizationInsurance: OrganizationInsurance;
  }
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ PatientInsurancePlanSearchComponent
      , FakeInsurancePlanSearchComponent ],
      imports: [
        StoreModule.forRoot({}),
        HttpClientModule,
        RouterTestingModule,
      ],
      providers: [
        Store,
        {
          provide: ActivatedRoute, useValue: {
            state: of({ selectedorganizationInsurancePlan: 'AETNA'})
        }
      },
      BillingHttpService
      ]
    })
    .compileComponents();
  }));

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

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

请指导我我缺少什么..

【问题讨论】:

    标签: angular unit-testing karma-jasmine


    【解决方案1】:

    如果你想将 patientId 添加到浏览器会话历史堆栈中,你可以简单地使用:

    history.pushState(state, title, url);
    

    在你的情况下应该是这样的:

    describe(MyComponent.name, () => {
       ...
    
       beforeEach(() => {
           window.history.pushState({ patientId: 'somevalue'}, '', '');
    
           ...
       })
    
    
       it('...', () => {
    
       })
    }
    

    【讨论】:

    • 请接受这是一个有效的答案:是一个完美的模拟
    • 这对我有用,谢谢。但是,当我使用 history.pushState(state, title, URL);在另一个模拟 history.state 的组件中,我的整个 Karma 测试停止,我收到一条 NOT FOUND 消息。有没有人遇到过这个?如果是这样,您知道如何解决此错误吗?干杯。
    【解决方案2】:

    简单回答:

    您可以提供状态:

    provideMockStore({ initialState: your_state })
    

    mockStore.setState(your_state );
    

    但是如果您有一个复杂的商店,我建议您执行以下操作:

    • 创建一个类,您将在其中拥有模拟存储状态:MockStoreState
    
    type RecursivePartial<T> = {
      [P in keyof T]?:
      T[P] extends (infer U)[] ? RecursivePartial<U>[] :
        T[P] extends object ? RecursivePartial<T[P]> :
          T[P];
    };
    
    export class MockStoreState {
      private store_a: RecursivePartial<Store_A>;
      private store_b: RecursivePartial<Store_b>;
    
      build(): any {
        const defaultStore_a = {
          ...
        };
        const defaultStore_b = {
          ...
        };
    
        return {
          store_a: { ...defaultStore_a , ...this.store_a},
          store_b: { ...defaultStore_b , ...this.store_b },
        };
      }
    
      setStore_a(value: RecursivePartial<Store_A>): Store_A_State {
        this.store_a= value;
        return this;
      }
    
      setStore_b(value: RecursivePartial<DatasourceState>): Store_B_State {
        this.store_b= value;
        return this;
      }
    }
    
    • 在测试中设置你的商店的状态:
    describe(MyComponent.name, () => {
       ...
       let mockStore: MockStore<any>;
    
       beforeEach(() => {
           ...
           mockStore = TestBed.get(Store);
       })
    
    
       it('...', () => {
         const state = new MockStoreState().setStore_a({...})
        .build();
    
        mockStore.setState(state);
    
       // HERE you have set the data in your store.
       })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多