Я пытаюсь проверить структурную директиву MyDirective с Jasmine. Используемая угловая версия - RC5.Угловые 2 RC5 Тестирование обещаний в ngOnInit Не работает
// Part of the MyDirective class
@Directive({selector: '[myDirective]'})
export class MyDirective {
constructor(protected templateRef: TemplateRef<any>,
protected viewContainer: ViewContainerRef,
protected myService: MyService) {
}
ngOnInit() {
this.myService.getData()
.then((data) => {
if (!MyService.isValid(data)) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
})
.catch((error) => {
console.log(error);
this.viewContainer.createEmbeddedView(this.templateRef);
});
}
}
Метод GetData перезаписывается в классе MockService, тогда как IsValid метод (статический метод MyService) вызывается непосредственно, который проверяет правильность данных.
// Part of the Jasmine unit test class for the MyDirective class
@Component({
selector: 'test-cmp', template: '', directives: [MyDirective]
})
class TestComponent {}
class MockService {
mockResponse: MyResponse = {valid date goes here};
mockInvalidResponse: MyResponse = {};
getData() {
if (booleanCondition) {
return Promise.resolve(this.mockResponse);
} else {
return Promise.resolve(this.mockInvalidResponse);
}
}
}
describe('MyDirective',() => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent],
providers: [
{provide: MyService, useClass: MockService},
TemplateRef,
ViewContainerRef
]
});
});
it('should remove the target DOM element when the condition is true', async(() => {
booleanCondition = true;
const template =
'<div><div *myDirective><span>Hi</span></div></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length).toEqual(0);
}));
it('should contain the target DOM element when the condition is false', async(() => {
booleanCondition = false;
const template =
'<div><div *myDirective><span>Hi</span></div></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
// The 'expect' bellow fails because the value is 0 for some reason
expect(getDOM().querySelectorAll(fixture.debugElement.nativeElement, 'span').length).toEqual(1);
}));
});
Второй it
предполагается создать случай, в котором элемент Спан находится в DOM, но это не так. Я проверил, будет ли он перейти к первому условию в следующих операциях if:
if (!MyService.isValid(data)) {
console.log('the first if condition is read.');
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
И он регистрирует его. Таким образом, он должен содержать элемент в DOM, но я не могу найти способ его протестировать.
Thanks @peeskillet! Я использовал первое из ваших двух решений, и он работал, как ожидалось.Вам не известно разницу между использованием «done()» Jasmine (передача проделанного параметра) и использованием [async] (https://angular.io/docs/ts/latest/api/core/testing/index/async -function.html)? [Исходный код Углового] (https://angular.io/docs/ts/latest/api/core/testing/index/async-function.html) использует 'async()' вместо 'done()'. Я пытаюсь понять, как 'async()' распознает все асинхронные вызовы. Это может стоить еще одного вопроса ... – jayscript
Я почти уверен, что это связано с зонами. Я все еще изучаю зоны, но я из того, что я сейчас понимаю, зонирует асинхронные методы polyfill, такие как 'setTimout' и т. Д., До такой степени, что зона знает обо всех асинхронных вызовах, сделанных в этой зоне. Зона ведет запись всех этих ожидающих задач. Проверьте [this out] (https://github.com/angular/zone.js/) –
Если вы посмотрите на [источник для 'async'] (https://github.com/angular/angular/blob/master /modules/%40angular/core/testing/async.ts), вы видите, что происходит много событий в зоне. Вы также увидите, что 'async' на самом деле вызывает' done', когда в среде жасмина –