【问题标题】:How would I mock route queryParams in ngOnInit() in a spec test如何在规范测试中模拟 ngOnInit() 中的路由 queryParams
【发布时间】:2021-01-28 09:27:45
【问题描述】:

失败:无法读取 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();

    });
  });
});

【问题讨论】:

  • 你为什么使用JSON.parse? 不是queryParams' 值应该是(简单)字符串?
  • @AndreiGătej 我将一个对象作为 queryParams 传递,您必须使用 JSON.stringify 来传递一个对象。因此,一旦我进入页面,我就必须对其进行解析以使其再次成为对象。

标签: angular typescript angular-routing angular-router angular2-testing


【解决方案1】:

无法读取 null 的属性“queryParams”

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

同样在您的代码中,您在queryParams 上调用subscribe(),因此您需要为该属性分配一个类似Observable 的对象。您可以通过使用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');
  });
});

【讨论】:

  • 感谢@Paul 的建议。我现在只有以下错误: Uncaught (in promise): SyntaxError: Unexpected token u in JSON at position 0 我正在使用 JSON.Parse,因为我在查询参数中将 IUser 对象传递给此页面。我必须对它进行字符串化才能传递对象,一旦我在页面上,我就会将它解析回一个对象。有一个更好的方法吗?我正在使用 Firebase 并试图将我的调用限制在后端。因此,除了 JSON 错误之外,所有其他错误都会发生。关于如何解决这个问题的任何想法?我用你的建议更新了我的代码 sn-p
  • fixture.detectChanges() 是一个疏忽...已将其删除,现在可以正常工作。谢谢@Paul
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2014-01-14
  • 2017-02-05
  • 1970-01-01
相关资源
最近更新 更多