ngOnChanges не вызывается в модульном тесте Angular 4 detectChanges()
Вопрос
У меня есть компонент кнопки, который принимает обещание и отключает кнопку до тех пор, пока обещание не будет разрешено, и я хочу написать модульный тест для этой функции.
Мой код
Мой компонент кнопки имеет вход для обещания
/**
* A single promise that triggers the busy state until it resolves
*/
@Input()
public promise: Promise<any>;
Внутри ngOnChanges я слушаю обещание
/**
* Enable button busy state until promise resolves
*/
if (changes && changes.promise && changes.promise.currentValue) {
this.busyUntilPromiseResolves(changes.promise.currentValue);
}
Затем я сохраняю массив активных обещаний, чтобы можно было передать несколько обещаний в
/**
* Add a promise that will keep the button in a busy state until it resolves
* @param activityProimise
*/
private busyUntilPromiseResolves(activityProimise) {
this.activityPromises.push(activityProimise);
activityProimise.then(() => {
this.activityPromises.splice(this.activityPromises.indexOf(activityProimise), 1);
});
}
Затем, наконец, в моем шаблоне я отключаю кнопку, если в массиве есть какие-либо обещания.
[disabled]="activityPromises.length > 0"
Помоги мне Оби-Ван
Я баловался и пробовал разные вещи, чтобы заставить это работать, это мой текущий тестовый код, который не работает. По сути, мне нужно проверить, что кнопка отключена до разрешения обещания, и затем я захочу провести еще один тест, который проверяет ее повторное включение после разрешения обещания.
it('should be disabled when passed a single promise', async((done) => {
let promise;
return promise = new Promise(resolve => {
component.promise = promise;
fixture.detectChanges();
expect(buttonElement.disabled).toBe(true);
return resolve();
});
}));
Как всегда, любая помощь будет оценена, спасибо.
2 ответа
Короткий ответ на этот вопрос заключается в том, что ngOnChanges не запускается автоматически во время модульных тестов, поэтому мне пришлось вызывать его вручную.
it('should be disabled when passed a single promise', async(() => {
let promise;
let resolve;
// should not be disabled here
expect(buttonElement.disabled).toBe(false);
// Pass a promise to the component to disable it
promise = new Promise(r => resolve = r);
component.ngOnChanges({
promise: new SimpleChange(null, promise, null)
});
fixture.detectChanges();
expect(buttonElement.disabled).toBe(true);
// now resolve the promise and make sure it's enabled again.
promise.then(() => {
fixture.detectChanges();
expect(buttonElement.disabled).toBe(false);
});
resolve();
}));
Вы пытались утверждать, прежде чем добавить это обещание?
it('should be disabled when passed a single promise', async(() => {
let promise;
// should not be disabledhere
expect(buttonElement.disabled).toBe(false);
let resolve;
const promise = new Promise(r => resolve = r);
component.promise = promise;
component.ngOnChanges(); // Call this here, TestBed doesn't know it needs to.
fixture.detectChanges();
expect(buttonElement.disabled).toBe(true);
// now resolve the promise and make sure it's disabled again.
resolve();
fixture.detectChanges();
expect(buttonElement.disabled).toBe(false);
}));
Изменить: как отмечено в комментариях, способ, которым вы устанавливаете это promise
свойство не работает с TestBed, поэтому оно никогда не вызывает ваш метод ngOnChanges(). Вы можете позвонить прямо, как я делал выше.
В качестве альтернативы, оберните ваш тестовый компонент в хост-компонент:
@Component({
selector: 'test-component',
template: `<my-component [promise]="promise"></my-component>`
})
class TestComponent {
promise;
}
// then use that in your test instead:
const wrapperCmp = TestBed.createComponent(TestComponent);
wrapperCmp.promise = promise; // and check for the button state before and after all the changes.