Для того, чтобы шпионить за методом, вам нужен экземпляр класса (тестируемая система или sut), которому принадлежит метод, так что метод может быть заменен шпионом.
spyOn<any>(sut, 'initializeForm');
Это означает, что рассматриваемый класс должен быть создан до того, как вы будете шпионить за его методами или свойствами, что легко сделать для того, чтобы шпионить за объектами, которые вы передаете конструктору в вашем методе beforeEach, или для методов, принадлежащих к sut, которые вызывается не самим конструктором, а потом.
Но так как вы хотите проверить, вызывает ли конструктор метод, но вам нужен экземпляр этого класса перед вызовом конструктора, чтобы шпионить за методом, который вызывается конструктором, но создавать экземпляр класса без его конструктор невозможен, вы столкнулись с дилеммой .
Мой совет - переместить вызов метода в метод ngOnInit и проверить его.
describe('constructor', () => {
it('should create the sut', () => {
expect(sut).toBeDefined();
});
});
describe('ngOnInit', () => {
it('should call initializeForm', () => {
spyOn<any>(sut, 'initializeForm');
sut.ngOnInit();
expect(sut.initializeForm).toHaveBeenCalled();
});
});
describe('initializeForm', () => {
it('should initialize the form', () => {
sut.initializeForm();
expect(sut.form).toBeDefined();
});
});
Да, простые формы могут быть созданы в вашем конструкторе. Но по мере того, как все усложняется, например, когда вы хотите получить доступ к значениям параметра @Input, метод ngOnInit является лучшим местом для начала создания формы.
Для того, чтобы Angular не выдавал ошибки шаблонов, либо предоставьте скрытую / пустую версию вашей формы в конструкторе, либо удерживайте HTML-код от рендеринга до тех пор, пока ngOnInit не пройдет и форма не будет определена с помощью * ngIf.
<form *ngIf="form" [formGroup]="form">
...
</form>