Жасмин использует шарики для проверки нескольких наблюдаемых значений - PullRequest
0 голосов
/ 30 октября 2019

Итак, я пытаюсь протестировать 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 голосов
/ 05 ноября 2019

Здесь вам не нужны жасминовые шарики. Пакет полезен при тестировании взаимодействия нескольких наблюдаемых, и у вас явно есть только одна. Для меня мраморы здесь выглядят излишними.

Проблема в последнем it () состоит в том, что вы заменяете значение alertService.alert $ другим наблюдаемым после того, как компонент подписался на начальное значение. Вот что происходит.

  1. В beforeEach создается шпионская служба, и холодный ('a', {a: testAlertGood}) назначается для оповещения $.
  2. В beforeEach компонентсоздано. Я полагаю, что он подписывается на предупреждение $ в ngOnInit () или через асинхронный канал.
  3. Компонент получает testAlertGood из наблюдаемой.
  4. it () запускается и назначает холодный ('a', {a: testAlertNoTitle}) для предупреждения $. Это ничего не меняет, потому что 2 и 3 уже произошли.

Я бы предложил здесь использовать старый добрый предмет вместо мрамора. Таким образом, вам не нужно менять наблюдаемое, но вы меняете его излучаемое значение. Как то так:

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