Жасмин использует шарики для проверки нескольких наблюдаемых значений
Итак, я пытаюсь протестировать 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$ другим наблюдаемым после того, как компонент подписался на начальное значение. Вот что происходит.
- В beforeEach создается шпионская служба, и для alert $ назначается холод ('a', { a: testAlertGood }).
- В beforeEach создается компонент. Я считаю, что он подписывается на предупреждение $ в ngOnInit() или через асинхронный канал.
- Компонент получает testAlertGood от наблюдаемого.
- 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();
});
});