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();
  }
}

Вы можете видеть все три альтернативы в этом повороте.

Другие вопросы по тегам