Ember компонент test - как работает компонентный тестовый компонент, когда он не вызывает внешнего действия?
Я немного новичок в Ember и пытаюсь проверить компонент пейджера. Упрощенный компонент выглядит так:
export default Ember.Component.extend({
index: 0,
actions: {
next() {
this.incrementProperty('index');
}
}
});
Я пытаюсь проверить, что действие next() действительно увеличивает свойство index, как и ожидалось. Я написал модульный тест, как это:
test('next should increment the index by 1', function (assert) {
const component = this.subject();
assert.equal(component.get('index'), 0, 'Index should be 0');
component.get('actions').next();
assert.equal(component.get('index'), 1, 'index should be 1');
});
Но происходит сбой с ошибкой "this.incrementProperty не является функцией". Отладка, "this" в тесте, когда она находится внутри функции next(), не является контекстом компонента - это объект с next() в качестве единственного свойства.
Мне интересно, если это из-за того, как я вызываю действие nextPlace в тесте. Я знаю, что мог бы написать интеграционный тест, который щелкает по кнопке, которая запускает это действие и сравнивает некоторый пользовательский интерфейс, чтобы убедиться, что он изменился, но это кажется очень запутанным, когда все, что я пытаюсь проверить, - это то, что сама функция работает так, как ожидалось. Если бы это действие было передано этому компоненту (закрытие), я знаю, что я мог бы установить фиктивную функцию в интеграционном тесте, передать ее компоненту и посмотреть, как он реагирует. Но это действие не вызывает действия, переданного ему.
Я понимаю, что функция, которую я тестирую, действительно базова, но отчасти она заключается в том, чтобы понять, как тестировать действия в компонентах, которые не вызывают внешнего (для компонента) действия.
1 ответ
Если бы вы не выразили свою мотивацию не писать интеграционный тест, я бы только предложил вам написать интеграционный тест. ИМО, твоя причина действительна. У меня есть 3 предложения для загрузки модульного теста для вашего случая.
Прежде всего: причина не работает "component.get('actions').next
получить ссылку на next
функционировать без какого-либо контекста. Так this
не является действительным в этом вызове. Чтобы сделать его действительным, просто привяжите к нему компонент, как показано ниже:
component.get('actions').next.bind(component)();
Но я бы не предпочел это, потому что это извлечение next
из его контекста и связать его снова. Мы делаем это bind
вещь, потому что мы знаем, что next
функция имеет ссылку на this
в своем коде.
Поэтому мое второе предложение - "как-то вызвать событие". Для запуска взгляните на следующий код:
component.send('next');
ИМО, это лучше. Нам не нужно знать "что дальше делать". Мы просто запускаем событие.
Но это касается жизненного цикла компонента ember. Мы принимаем эту ситуацию: существует определенный хеш, называемый actions
и мы можем запустить его через send
, (Это совершенно нормально.) Вместо того, чтобы иметь дело с actions
мы можем отделить doing something
от action handling
, Таким образом, вы можете определить другую функцию, которая будет делать то, что вам нужно, и просто вызвать ее из вашего обработчика действий. (Хорошо, в этом случае нам снова нужно знать, какая функция вызывается обработчиком действия. Но это кажется мне более понятным.) Как показано ниже:
next(){
this.incrementProperty('index');
},
actions:{
next(){
this.next();
}
}
Вы можете видеть все три альтернативы в этом повороте.