我如何在规范测试中模拟 ngOnInit() 中的路由查询参数

How would I mock route queryParams in ngOnInit() in a spec test

失败:无法读取 null 的 属性 'queryParams' 在

我假设这是因为我在 ngOnInit() 中有以下内容:

  ngOnInit() {
    this.route.queryParams.subscribe(async params => {
      this.userInfo = await JSON.parse(params['user_info']);
    });

到目前为止,我已尝试使用以下方法构建我的单元测试:

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

  beforeEach(async(() => {
    routeStub = null;

    TestBed.configureTestingModule({
      declarations: [ AddItineraryPage ],
      imports: [IonicModule.forRoot(), FormsModule, ReactiveFormsModule, RouterTestingModule],
      providers: [
        {provide: ActivatedRoute, useValue: routeStub}
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(AddItineraryPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    routeStub.queryParams = {
    displayName: '',
    dateOfBirth: '',
    email: '',
    photos: [],
    location: '',
    bio: '',
    intDestination: [],
    userId: ''};

    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect(component).toBeTruthy();

    });
  });
});

Cannot read property 'queryParams' of null

所以当在 routeStub 对象上调用 属性 queryParams 时,它是空的。您将 routeStub 初始化为 null,所以这是有道理的。 ngOnInit() 在您第一次调用 fixture.detectChanges() 时被调用,因此您需要在 进行调用之前为 routeStub 分配一些内容。

同样在您的代码中,您在 queryParams 上调用了 subscribe(),因此您需要将一个 Observable-like 对象分配给 属性。您可以使用 Observable.of().

来使用实际的 Observable

所以你的测试代码应该更像

beforeEach(async(() => {
  routeStub = null;
  ...
  fixture = TestBed.createComponent(AddItineraryPage);
  component = fixture.componentInstance;
  // remove fixture.detectChanges() as it calls ngOnInit()
}));

it('should create', () => {
  routeStub = {
    queryParams: of({
      user_info: '{
        "displayName": "UserName"
      }'
      // not sure why you are calling `JSON.parse()`
      // but if you are doing that, then user_info should
      // be a JSON string
    })
  };

  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(component.userInfo.displayName).toBe('UserName');
  });
});