Angular - Как выполнить модульное тестирование компонента с помощью асинхронного вызова службы
У меня есть следующий компонент, который извлекает данные из службы Angular:
export class MyComponent {
constructor() {
myService.get().then(() => {
console.log('hello from constructor');
});
}
}
А потом мой юнит тест:
///////////
it('does something', () => {
console.log('hello from unit test');
});
///////////
К сожалению, это приводит к следующему журналу:
> hello from unit test
> hello from constructor
Как я могу убедиться, что конструктор завершает работу до запуска модульного теста?
2 ответа
Не используйте конструктор для загрузки данных, реализуйте OnInit
интерфейс вместо.
import { OnInit } from '@angular/core';
export class MyComponent implements OnInit {
constructor(private myService: MyService) {}
ngOnInit() {
myService.get().then(() => {
console.log('hello from constructor');
});
}
}
- См. Также угловую документацию Lifecycle Hooks.
- Не забывайте вводить свои зависимости как
myService
Например, я добавил его в конструктор.
тестирование
Я рекомендую вам прочитать документацию по тестированию. Информации много, но оно того стоит. Вот код, который вы бы использовали для модульного тестирования вашего компонента.
let comp: MyComponent ;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
providers: [
{ provide: MyService, useValue: {} }
]
})
.compileComponents();
TestBed.compileComponents();
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
}));
it('initializes the component', fakeAsync(() => {
var service = TestBed.get(MyService); // get your service
service.get = () => {
return Promise.resolve(); // you can pass data here if the service returns something
};
// here you could add an expect to validate component state before the call or service completes
comp.ngOnInit(); // call ngOnInit
tick(); // simulate the promise being resolved
expect(service.get.toHaveBeenCalled);
// here you could add an expect to validate component state after the service completes
}));
Ваш конструктор выполняется перед вашими тестами, однако код вашего конструктора выполняет асинхронный вызов службы, который выполняется после ваших тестов.
Во-первых, вы должны рассмотреть возможность удаления вызова службы из конструктора.
Во-вторых, когда вы пишете тесты для компонента, вы обычно следите за сервисными вызовами и проверяете, что они были вызваны, вы на самом деле не делаете вызов, вы его макетируете. Посмотрите документацию для "spyOn".
И наконец, если вы хотите, чтобы что-то произошло перед вашими тестами, взгляните на 'beforeEach'. В любом случае, надеюсь, это поможет.