Тестирование Vue: shallowMount и localVue выдают ошибку при втором запуске идентичного теста. Разве они не являются чистыми функциями? - PullRequest
1 голос
/ 13 июня 2019

Итак, я пытаюсь настроить некоторые модульные тесты для своего приложения и сталкиваюсь со следующей проблемой.Запуск точно такого же теста приводит к ошибке в shallowMount во второй раз.По трассировке стека я могу сказать, что она связана с пользовательской директивой v-intro (см .: https://github.com/alex-oleshkevich/vue-introjs). Удаление ее из моего шаблона компонента устраняет ошибку, но я хочу понять, почему это происходит в первую очередь.

<template>
  <div class="container" v-intro="'Hello world'" v-intro-step="1">
    ...
  </div>
</template>

<script>
export default {
  mounted() {
    this.$intro().start()
  }
//etc
}

</script>
x import Campaign from '../campaigns';                                                                                                                                                                                                        
  import {createLocalVue, shallowMount} from '@vue/test-utils';                                                                                                                                                                               
  import notifyCustom from '../../objects/notifier';                                                                                                                                                                                          
  import VueIntro from 'vue-introjs';                                                                                                                                                                                                         
  import dataProvider from '../../dataProvider';                                                                                                                                                                                              

  const localVue = createLocalVue();                                                                                                                                                                                                          
  localVue.use(notifyCustom);                                                                                                                                                                                                                 
  localVue.use(VueIntro);                                                                                                                                                                                                                     

  describe('TESTING THE CAMPAIGNS CONTAINER', () => {                                                                                                                                                                                         
    test('it displays campaigns', () => {                                                                                                                                                                                                     
      let wrapper1 = shallowMount(Campaign, {                                                                                                                                                                                                 
        localVue,                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                     
      //fine                                                                                                                                                                                                                                  
      let wrapper2 = shallowMount(Campaign, {                                                                                                                                                                                                 
        localVue,                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                     
      //fine                                                                                                                                                                                                                                  
      let wrapper3 = shallowMount(Campaign, {                                                                                                                                                                                                 
        localVue,                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                     
      //fine                                                                                                                                                                                                                                  
      let wrapper4 = shallowMount(Campaign, {                                                                                                                                                                                                 
        localVue,                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                     
      //fine                                                                                                                                                                                                                                  
      expect(wrapper1.text()).toContain('Campaign');                                                                                                                                                                                           
      //test passes                                                                                                                                                                                                                           
    });                                                                                                                                                                                                                                       

    test('renders campaigns', () => {                                                                                                                                                                                                         
      let wrapper5 = shallowMount(Campaign, {                                                                                                                                                                                                 
        localVue,                                                                                                                                                                                                                             
      });                                                                                                                                                                                                                                     
      //error                                                                                                                                                                                                                                 
      expect(wrapper5.text()).toContain('Campaign');                                                                                                                                                                                           
    });                                                                                                                                                                                                                                       
  });              

трассировка стека:

  console.error node_modules/vue/dist/vue.runtime.common.dev.js:621                                                                                                                                                                           
    [Vue warn]: Error in directive intro bind hook: "TypeError: Cannot read property 'tagName' of undefined"                                                                                                                                  

    found in                                                                                                                                                                                                                                  

    ---> <Anonymous>                                                                                                                                                                                                                          
           <Root>                                                                                                                                                                                                                             

  console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884                                                                                                                                                                          
    TypeError: Cannot read property 'tagName' of undefined                                                                                                                                                                                    
        at Array.updateDOMProps (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6970:32)                                                                                                                          
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6288:62)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at updateChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6167:9)                                                                                                                                 
        at patchVnode (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6293:29)                                                                                                                                    
        at VueComponent.patch [as __patch__] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6454:9)                                                                                                              
        at VueComponent.Vue._update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:3930:19)                                                                                                                      
        at VueComponent.updateComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4048:10)                                                                                                                  
        at Watcher.get (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)                                                                                                                                   
        at Watcher.run (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4534:22)            
        at flushSchedulerQueue (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4292:13)    
        at queueWatcher (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4381:9)            
        at Watcher.update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4524:5)          
        at Dep.notify (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:732:13)              
        at Object.reactiveSetter [as timer] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:1057:11)                                                                                                              
        at VueComponent.proxySetter [as timer] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4611:26)                                                                                                           
        at VueComponent.ready (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/timer.js:16:22)                                                                                                                  
        at VueComponent.restartTimer (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/timer.js:21:18)                                                                                                           
        at ping (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/directives/intro.js:4:35)                                                                                                                      
        at callHook$1 (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6652:7)              
        at _update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6573:7)                 
        at Array.updateDirectives (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6554:5)  
        at invokeCreateHooks (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6043:22)      
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5930:11)              
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9) 
        at VueComponent.proxySetter [as timer] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4611:26)
        at VueComponent.ready (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/timer.js:16:22)
        at VueComponent.restartTimer (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/timer.js:21:18)
        at ping (/home/andreas/work/proteus/node_modules/vue-introjs/dist/webpack:/default/src/directives/intro.js:4:35)
        at callHook$1 (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6652:7)              
        at _update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6573:7)                 
        at Array.updateDirectives (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6554:5)  
        at invokeCreateHooks (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6043:22)      
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5930:11)              
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at createChildren (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6027:9)          
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5928:9)               
        at VueComponent.patch [as __patch__] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6449:7)
        at VueComponent.Vue._update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:3927:19)
        at VueComponent.updateComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4048:10)
        at Watcher.get (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)            
        at new Watcher (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)            
        at mountComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)          
        at VueComponent.Object.<anonymous>.Vue.$mount (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
        at init (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:3112:13)                   
        at createComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5952:9)         
        at createElm (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:5899:9)               
        at VueComponent.patch [as __patch__] (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:6449:7)
        at VueComponent.Vue._update (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:3927:19)
        at VueComponent.updateComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4048:10)
        at Watcher.get (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)            
        at new Watcher (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)            
        at mountComponent (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)          
        at VueComponent.Object.<anonymous>.Vue.$mount (/home/andreas/work/proteus/node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
        at mount (/home/andreas/work/proteus/node_modules/@vue/test-utils/dist/vue-test-utils.js:8649:21)              
        at shallowMount (/home/andreas/work/proteus/node_modules/@vue/test-utils/dist/vue-test-utils.js:8677:10)       
        at Object.<anonymous> (/home/andreas/work/proteus/app/javascript/packs/containers/__tests__/campaigns.spec.js:49:20)
        at Object.asyncJestTest (/home/andreas/work/proteus/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
        at resolve (/home/andreas/work/proteus/node_modules/jest-jasmine2/build/queueRunner.js:43:12)                  
        at new Promise (<anonymous>)                       
        at mapper (/home/andreas/work/proteus/node_modules/jest-jasmine2/build/queueRunner.js:26:19)                   
        at promise.then (/home/andreas/work/proteus/node_modules/jest-jasmine2/build/queueRunner.js:73:41)             
        at process._tickCallback (internal/process/next_tick.js:68:7)                                                  

Test Suites: 1 failed, 1 total                             
Tests:       2 failed, 2 total                             
Snapshots:   0 total         
Time:        1.294s          
Ran all test suites matching /campaign/i.                  
error Command failed with exit code 1.                     
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.         

1 Ответ

1 голос
/ 14 июня 2019

Этот загнал меня вверх по стене, но мне удалось выделить проблему и найти два отличных обходных пути.Первым было ввести хук beforeEach для каждого теста и использовать требование для загрузки вступительного плагина:

let wrapper;
beforeEach(() => {
  const notifyCustom = require('../../objects/notifier');
  const VueIntro = require('vue-introjs');
  const localVue = createLocalVue();
  localVue.use(VueIntro);
  localVue.use(notifyCustom);
  wrapper = shallowMount(Campaign, {localVue})
});

Очевидно, что в плагине VueIntro есть некоторая информация о состоянии.То, что это точно, в данный момент мне недоступно.Хотя это решение устранило ошибку, оно оставило мне кучу предупреждений, загромождающих результаты моего теста.В конце концов, я понял, что могу просто заглушить директивы компонента и de v-intro / v-intro-step и наслаждаться видом тестов, зеленеющих в блаженном молчании.

// see: https://vue-test-utils.vuejs.org/api/config.html                                                                                                                                                                                                                                                                                                                     config.stubs['notifications'] = '<div />'; 
                                                                                                                                                                                             const localVue = createLocalVue();                                                                                                                                                                                                                                                                                                                                                                                                                                                          
//see https://github.com/vuejs/vue-test-utils/issues/450                                                                                                                                                                                      
// jsfiddle @ https://jsfiddle.net/smsjfz5r/4/                                                                                                                                                                                                
// solves  [Vue warn]: Failed to resolve directive: intro-step                                                                                                                                                                                
localVue.directive('intro', {                                                                                                                                                                                                                 
  inserted: function(el) {                                                                                                                                                                                                                    
    return;                                                                                                                                                                                                                                   
  },                                                                                                                                                                                                                                          
});                                                                                                                                                                                                                                           
localVue.directive('intro-step', {                                                                                                                                                                                                            
  inserted: function(el) {                                                                                                                                                                                                                    
    return;                                                                                                                                                                                                                                   
  },                                                                                                                                                                                                                                          
});                                                                                                                                                                                                                                           

const getWrapper = () => {                                                                                                                                                                                                                    
  return shallowMount(Campaign, {localVue});                                                                                                                                                                                                  
};    

Во всяком случае, не идеальное решение, но, по крайней мере, теперь я могу двигаться дальше.Если кто-нибудь сможет пролить свет на состояние этих плагинов Vue, я все равно буду признателен ...

...