首页 > 解决方案 > 测试 Angular 组件,该组件引入从 @angular-redux/store 的“@select()”方法派生的 observable

问题描述

好的。所以我有一个名为“Account”的组件,它使用@select() 来生成 user$。user$ 的类型是一个带有“User”接口的 Observable

@select user$: Observable<User>

我还有一个名为“用户”的变量。在这个组件的构造函数中,我订阅了“user$”,并从 observable 中派生了 'user' 的属性。

constructor(private ngRedux: NgRedux<gdcClientState>, private dbService: DatabaseService){
 this.user$.subscribe(user => this.user = user)
}

这在实践中效果很好,但是当我尝试测试时,我立即遇到一个关于它如何无法读取未定义的“firstName”的错误。 *由可观察的“用户$”设置为“用户”的属性之一是名字。

这是我的测试的样子:

/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import {NgReduxTestingModule, MockNgRedux} from '@angular-redux/store/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { DatabaseService } from '../database.service';
import { User } from '../user'; 
import { Observable } from 'rxjs';

import { AccountComponent } from './account.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AccountComponent ],
      imports: [NgReduxTestingModule, FormsModule, ReactiveFormsModule],
      providers: [
        {provide: DatabaseService}
      ]
    })
    .compileComponents();
  }));


  beforeEach(()=>{
    MockNgRedux.reset();

    fixture = TestBed.createComponent(AccountComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

  });

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






  it('should create', async(() => {
    const fixture = TestBed.createComponent(AccountComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;


 fixture.detectChanges();

    expect(compiled).toBeTruthy();
  }));
});

我尝试从这两个线程中实现一些修复和建议:Testing @select decorators with @angular-redux/store Testing Angular with @angular-redux/store in Storybook

但这对我没有用。我希望得到一些帮助。谢谢你。

标签: angularreduxjasminekarma-jasmineangular-redux

解决方案


你不应该在组件的构造函数上初始化订阅,而是在ngOnInit生命周期钩子上。

ngOnInit(){
 this.user$.subscribe(user => this.user = user)
}

在您的规范中,请确保user在触发第一个detectChanges. 所以最好创建一个mockUser并将其设置在那里:

    fixture = TestBed.createComponent(AccountComponent);
    component = fixture.componentInstance;
    component.user = mockUser;
    fixture.detectChanges();

干杯!


推荐阅读