Жасмин использует шарики для проверки нескольких наблюдаемых значений

Итак, я пытаюсь протестировать 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 ответ

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

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

  1. В beforeEach создается шпионская служба, и для alert $ назначается холод ('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();
    });
});
Другие вопросы по тегам