Модульное тестирование Vue.js ErrorBoundary

Я создал простой компонент ErrorBoundary для своего проекта на Vue.js, и я изо всех сил пытаюсь написать для него модульный тест. Код компонента ниже:

<template>
  <div class="overvue-error-boundary">
    <slot v-if="!error" />
    <div class="error-message" v-else>Something went horribly wrong here.</div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      error: false
    }
  },
  errorCaptured (error, vm, info) {
    this.error = true;
  }
}
</script>

Я создал ErrorThrowingComponent, который выдает ошибку в обработчике жизненного цикла created (), поэтому я могу проверить ErrorBoundary:

const ErrorThrowingComponent = Vue.component('error-throwing-component', {
  created() {
    throw new Error(`Generic error`);
  },
  render (h) {
    return h('div', 'lorem ipsum')
  }
});

describe('when component in slot throws an error', () => {
  it('renders div.error-message', () => {
  // this is when error is when 'Generic error' is thrown by ErrorThrowingComponent
  const wrapper = shallowMount(OvervueErrorBoundary, {
    slots: {
      default: ErrorThrowingComponent
    }});
    // below code is not executed
    expect(wrapper.contains(ErrorThrowingComponent)).to.be.false;
    expect(wrapper.contains('div.error-message')).to.be.true;
  });
});

Проблема в том, что ErrorThrowingComponent выдает ошибку, когда я пытаюсь его смонтировать (что приводит к провалу всего теста). Есть ли способ предотвратить это?

РЕДАКТИРОВАТЬ: то, что я пытаюсь достичь, - это фактически смонтировать компонент ErrorThrowing в слот по умолчанию компонента ErrorBoundary, чтобы проверить, будет ли ErrorBoundary отображать сообщение об ошибке, а не слот. Именно так я и создал ErrorThrowingComponent. Но я не могу утверждать поведение ErrorBoundary, потому что получаю сообщение об ошибке при попытке создать оболочку.


person rufus1530    schedule 24.11.2018    source источник
comment
что значит "выдает ошибку при установке"? ... При создании возникает ошибка ... (или я что-то упустил ??)   -  person Aviad    schedule 25.11.2018
comment
Я разъяснил это в разделе ИЗМЕНИТЬ выше.   -  person rufus1530    schedule 25.11.2018
comment
вызывается errorCaptured? Можете ли вы попробовать добавить туда журнал и посмотреть, не связана ли проблема с устройством захвата?   -  person Aviad    schedule 25.11.2018
comment
@Aviad, да, у компонента ErrorBoundary есть ловушка errorCaptured (), которая работает. Компонент работает как надо, просто я не могу написать для него модульный тест с помощью vue-test-utils.   -  person rufus1530    schedule 25.11.2018
comment
попробуйте рефакторинг компонента Errorboundry, чтобы использовать такую ​​функцию рендеринга: github.com/dillonchanis/vue-error-boundary/blob/master/src/ LMK если что-то меняет? это может указывать на возможную проблему в том, как макет интерпретирует функцию рендеринга по сравнению с шаблонами рендеринга.   -  person Aviad    schedule 25.11.2018
comment
@Aviad, нет, к сожалению, ошибка все еще выдается ... Может, есть другой способ это проверить? Компонент ErrorBoundary, кстати, работает после рефакторинга.   -  person rufus1530    schedule 25.11.2018
comment
Это может быть связано с основной реализацией vue-test-utils. Похоже, что при vue-test-utils анализе шаблонов может быть ошибка. Может быть, откроем баг в их репо :)   -  person Aviad    schedule 25.11.2018
comment
@Aviad, спасибо за помощь, я проверил с людьми из Vue Land, и они предложили мне другой подход, который решает мою проблему. Вы можете найти это в моем ответе.   -  person rufus1530    schedule 25.11.2018


Ответы (1)


Для тех, кто сталкивается с подобной проблемой: я поднял это на канале Vue Land # vue-testing на Discord, и они предложили переместить всю логику обработки ошибок в функцию, которая будет вызываться из хука errorCaptured (), и тогда просто проверьте эту функцию. Мне такой подход кажется разумным, поэтому я решил разместить его здесь.

Отредактированный компонент ErrorBoundary:

<template>
  <div class="error-boundary">
    <slot v-if="!error" />
    <div class="error-message" v-else>Something went horribly wrong here. Error: {{ error.message }}</div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      error: null
    }
  },
  methods: {
    interceptError(error) {
      this.error = error;
    }
  },
  errorCaptured (error, vm, info) {
    this.interceptError(error);
  }
}
</script>

Модульный тест с использованием vue-test-utils:

describe('when interceptError method is called', () => {
  it('renders div.error-message', () => {
    const wrapper = shallowMount(OvervueErrorBoundary);
    wrapper.vm.interceptError(new Error('Generic error'));
    expect(wrapper.contains('div.error-message')).to.be.true;
  });
});
person rufus1530    schedule 25.11.2018