簡體   English   中英

Jasmine 使用彈珠測試多個可觀察值

[英]Jasmine using marbles to test multiple observable values

因此,我正在嘗試根據可觀察對象是否發出某些值來測試 HTML。 我已經對服務進行了初始設置,以使 observable 發出正確的值,但是當我 go 創建另一個測試來測試如果我傳遞錯誤數據會發生什么時,我無法更改 observable 發出的值。 我覺得我錯過了一些小東西,有人可以看看,讓我知道我做錯了什么嗎?

這是規格文件

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 });

你在這里不需要茉莉花大理石。 package 在測試多個可觀察對象的交互時很有用,而您顯然只有一個。 對我來說,彈珠在這里看起來有點矯枉過正。

最后一個 it() 的問題是,在組件訂閱了初始值之后,您將 alertService.alert$ 的值替換為另一個 observable。 這就是發生的事情。

  1. 在 beforeEach 中創建了間諜服務,並且將 cold('a', { a: testAlertGood }) 分配給了 alert$。
  2. 在 beforeEach 中創建組件。 我相信它在 ngOnInit() 或通過異步 pipe 訂閱 alert$。
  3. 組件從 observable 中獲取 testAlertGood。
  4. it() 啟動並將cold('a', { a: testAlertNoTitle }) 分配給alert$。 它不會改變任何事情,因為 2 和 3 已經發生了。

我建議在這里使用一個好的舊主題而不是彈珠。 所以你不需要改變 observable,但是你改變它的發射值。 像這樣的東西:

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
    };
    
    const alertSubj = new Subject<any>();

    beforeEach(async(() => {
        alertService = jasmine.createSpy('AlertService');
        alertService.alert$ = alertSubj.asObservable();

        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 () => {
        alertSubj.next(testAlertGood);
        
        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 () => {
        alertSubj.next(testAlertNoTitle);

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM