Мокінг функції Observable у юніт-тестах Angular

текст перекладу
pic

Налаштування тестового середовища:

  • Імпортуємо необхідні модулі:
import { ComponentFixture, TestBed } from '@angular/core/testing';  
import { MyComponent } from './my.component'; // Ваш компонент для тестування  
import { MyService } from './my.service'; // Сервіс з функцією Observable  
import { of } from 'rxjs'; // Для створення моків для обсерваблів
  • Налаштування TestBed:
describe('MyComponent', () => {  
 let component: MyComponent;  
 let fixture: ComponentFixture;  
 let mockMyService: jasmine.SpyObj; // Створюємо мок об'єкта  

 beforeEach(async () => {  
 await TestBed.configureTestingModule({  
 declarations: [MyComponent],  
 providers: [  
 { provide: MyService, useValue: mockMyService } // Перевизначаємо сервіс за допомогою моку  
 ]  
 })  
 .compileComponents();  
 });  

 beforeEach(() => {  
 fixture = TestBed.createComponent(MyComponent);  
 component = fixture.componentInstance;  
 mockMyService = TestBed.inject(MyService) as jasmine.SpyObj; // Інжектимо мок  
 fixture.detectChanges(); // Виявляємо зміни після інжекції сервісу  
 });  
});
  • Це створює TestBed для вашого компонента та надає мок-екземпляр MyService за допомогою useValue.

Мокінг функції Observable:

  • Створення мок об'єкта:
beforeEach(() => {  
 mockMyService = jasmine.createSpyObj('MyService', ['myObservableFunction']); // Мок для функції  
});

Визначення поведінки мока:

  • Повернення певного значення:
mockMyService.myObservableFunction.and.returnValue(of([1, 2, 3])); // Повертаємо масив чисел
  • Моделювання помилки:
mockMyService.myObservableFunction.and.throwError(new Error('Simulated error'));
  • Контроль за завершенням:
const subject = new Subject();  
mockMyService.myObservableFunction.and.returnValue(subject);  
subject.next([4, 5, 6]); // Випускаємо значення пізніше в тесті

3. Написання юніт-тестів:

  • Тестування поведінки компонента на основі виходу Observable:
it('should display data when observable emits values', () => {  
 const expectedData = [1, 2, 3];  
 mockMyService.myObservableFunction.and.returnValue(of(expectedData));  

 component.fetchData(); // Викликаємо функцію, що ініціює observable  
 fixture.detectChanges(); // Виявляємо зміни після виклику функції  

 const element = fixture.nativeElement.querySelector('p'); // Або використовуйте відповідний селектор  
 expect(element.textContent).toBe(expectedData.join(', '));  
});  

it('should handle errors from the observable', () => {  
 mockMyService.myObservableFunction.and.throwError(new Error('Simulated error'));  

 expect(() => component.fetchData()).toThrowError('Simulated error');  
});

Не забувайте адаптувати селектори та перевірки відповідно до логіки вашого компонента та структури шаблону.

Додаткові міркування:

  • Розширене мокінгування: Для більш складних сценаріїв мокінгу розгляньте бібліотеки, такі як Sinon або NgRx/store/testing.
  • Тестування марблів: Досліджуйте Marble Testing з RxJS для складних тестових випадків, що залучають взаємодії між обсерваблями.

Перекладено з: Mocking an Observable Function in Angular Unit Tests

Leave a Reply

Your email address will not be published. Required fields are marked *