茉莉花用大理石测试多个可观察值

时间:2019-10-30 14:03:40

标签: angular jasmine karma-jasmine rxjs-marbles

因此,我试图根据可观察对象是否发出某些值来测试HTML。我已经在服务的初始设置中设置了一个可观察的对象发出正确的值,但是当我创建另一个测试来测试如果我传递错误的数据会发生什么情况时,我无法更改该可观察对象发出的值。我觉得我缺少的东西很小,有人可以看一下让我知道我在做什么错吗?

这是规格文件

describe('AlertsComponent', () => {
  let component: AlertsComponent;
  let fixture: ComponentFixture<AlertsComponent>;
  let alertService: any;

  let testAlertGood: Alert = {
    type: AlertType.Success,
    title: 'Test title',
    message: 'Test message',
    forceAction: false
  };

  let testAlertBad: String = 'bad alert';

  let testAlertNoTitle: Alert = {
    type: AlertType.Success,
    title: null,
    message: 'Test message',
    forceAction: false
  };

  beforeEach(async(() => {
    alertService = jasmine.createSpy('AlertService');
    alertService.alert$ = cold('a', { a: testAlertGood });

    TestBed.configureTestingModule({
      declarations: [ AlertsComponent ],
      schemas: [ NO_ERRORS_SCHEMA ],
      providers: [
        {
          provide: Router,
          useClass: class { navigate = jasmine.createSpy('navigate'); }
        },
        {
          provide: AlertService,
          useValue: alertService
        }
      ]
    })
    .compileComponents();
  }));

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

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

  it('should display an alert if the alert$ observable has an Alert value', async () => {
    fixture.detectChanges();
    getTestScheduler().flush();
    fixture.detectChanges();

    const alertElements = fixture.debugElement.queryAll(By.css('.alert-container'));
    const alertIconContainer = fixture.debugElement.query(By.css('.icon-container'));
    const alertIconClass = fixture.debugElement.query(By.css('#alert-icon'));
    const alertTitle = fixture.debugElement.query(By.css('.title'));
    const alertBody = fixture.debugElement.query(By.css('.body'));

    expect(alertElements.length).toBe(1);
    expect(alertIconContainer.nativeElement.getAttribute('class')).toContain('bg-success');
    expect(alertIconClass.nativeElement.getAttribute('class')).toContain('fa-check-circle');
    expect(alertTitle.nativeElement.innerText).toContain('Test title');
    expect(alertBody.nativeElement.innerText).toContain('Test message');
  });

  it('should hide the title p tag if the Alert.title is null', async () => {
    alertService.alert$ = cold('a', { a: testAlertNoTitle });

    fixture.detectChanges();
    getTestScheduler().flush();
    fixture.detectChanges();

    const alertTitle = fixture.debugElement.query(By.css('.title'));
    expect(alertTitle).toBeNull();
  });
});

因此,基本上在文件的顶部,我具有三个值的版本,这些值需要在可观察对象发出时进行测试,而我只能测试第一个。 should display an alert if the alert$测试通过得很好,但是它的最后一个should hide the title...失败了,因为它在我执行alertService.alert$ = cold('a', { a: testAlertNoTitle });

时似乎并没有改变可观察性

1 个答案:

答案 0 :(得分:0)

这里不需要茉莉花大理石。当测试多个可观察对象的交互时,该包非常有用,您显然只有一个。对我来说,大理石在这里看起来像是过分杀伤了。

最后一个it()中的问题是,在组件订阅了初始值之后,您用另一个可观察到的值替换了alertService.alert $的值。这就是发生的情况。

  1. 在beforeEach中创建间谍服务并将Cold('a',{a:testAlertGood})分配给alert $。
  2. 在beforeEach中创建组件。我相信它在ngOnInit()或通过异步管道订阅了alert $。
  3. 该组件从可观察对象获得testAlertGood。
  4. it()启动,并将cold('a',{a:testAlertNoTitle})分配给alert $。不会改变任何事情,因为2和3已经发生。

我建议您在这里使用老字号代替大理石。因此,您无需更改可观察值,但可以更改其发射值。像这样:

<div *ngFor="let presentation of presentations">
   <div [ngStyle]="{'background-image': 'url('+getUrl(presentation.slides[0].slideid)+')'}">
</div>