【问题标题】:Reset Vue for every jest test?为每个玩笑测试重置 Vue?
【发布时间】:2020-06-29 07:56:36
【问题描述】:

我正在使用带有 @vue/test-utils 和 jest 的 Vue JS。我打电话给我的测试:

let localVue = createLocalVue();
vueMount(MyComponent, { localVue: localVue, options });

问题是,我正在引用执行以下操作的库:

import Vue from 'vue'
import Msal from 'vue-msal'
//...
Vue.use(Msal, {...});

Vue.use() 在原型上注册了一些全局的东西,等等。出于测试目的,我需要这个来重新开始每个测试。我唯一能想到的就是在 Vue 对象上使用 mockImplementation() 和 jest。但如果可能的话,我不太确定如何做到这一点。

有没有办法做到这一点?谢谢!

【问题讨论】:

  • Local Vue 用于独立的单元测试。如果您想在单元测试中使用所有第三方库(顺便说一句,这不是一个好的测试策略),本地 Vue 就没有用了。

标签: vue.js jestjs vue-test-utils


【解决方案1】:

我花了一段时间,但这是我解决这个问题的方法......

let setupComplete = false;
let setupFailure = false;
let testContext = {};

function resetTestContext() {
  Object.keys(testContext).forEach(function(key) { delete testContext[key]; });
}

function createTestContext(configureTestContext) {
  beforeEach(() => {
    jest.isolateModules(() => {
      setupFailure = true;
      jest.unmock('vue');
      resetTestContext();
      testContext.vueTestUtils = require('@vue/test-utils');
      testContext.vue = testContext.vueTestUtils.createLocalVue();
      jest.doMock('vue', () => testContext.vue);
      testContext.vuetify = require('vuetify');
      testContext.vue.use(testContext.vuetify);
      testContext.vuetifyInstance = new testContext.vuetify();
      if (configureTestContext) {
        configureTestContext(testContext);
      }
      setupComplete = true;
      setupFailure = false;
    });
  });

  afterEach(() => {
    setupComplete = false;
    resetTestContext();
    jest.resetModules();
    setupFailure = false;
  });

  return testContext;
},

使这成为可能的是 jest.isolateModules() 方法。通过这种方法,Vue 和它的原型,还有 Vuetify,在每个测试用例中都被完全重新创建并焕然一新。

为了使其正常工作,测试规范和包含上述实用程序的库可能不会“导入”Vue 或任何依赖于 Vue 的模块。相反,它需要在 configureTestContext() 函数或测试用例本身中。

我的测试规范如下所示:

import createTestContext from '@/scripts/createTestContext'

describe('sample', () => {
  const testContext = createTestContext(function configureTestContext(testContext)
  {
    testContext.vueDependency = require('@/scripts/vueDependency').default;
  });

  test('demo', () => {
    // I added a helper to more easily do this in the test context...
    const sample = testContext.vueTestUtils.mount(require('@/components/Sample').default, {
      localVue: testContext.vue,
      vuetify: testContext.vuetifyInstance
    });

    expect(testContext.vueDependency.doSomething(sample)).toBe(true);
    expect(sample.isVueInstance()).toBeTruthy();
  });
});

【讨论】:

    【解决方案2】:
    import { shallowMount, createLocalVue } from '@vue/test-utils';
    import Vuex from 'vuex';
    
    const localVue   = createLocalVue();
    const { user }   = require('./customer.mock');
    const originUser = { ...user };
    
    const resetUserData = wrapper => {
        wrapper.setData( { userData: originUser } );
    };
    
    const TestComponent = localVue.component( 'TestComponent', {
        name : 'TestComponent',
    
        data : () => {
            return { userData: user };
        },
    
        render( createElement ) {
            return createElement( 'h3', 'hoy hoy' );
        },
    } );
    
    describe( 'computed fields', () => {
        afterEach( () => {
            resetUserData( wrapper );
        } );
    
        it( 'isPrivatePerson should return false', () => {
            wrapper.setData( { userData: { Contacts: [{ grpid: 'bad field' }] } } );
    
            expect( !wrapper.vm.isPrivatePerson ).toBeTruthy();
        } );
        it( 'isPrivatePerson should return true', () => {
            expect( wrapper.vm.isPrivatePerson ).toBeTruthy();
        } );
    });
    

    【讨论】:

    • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请编辑您的答案以添加一些解释,包括您所做的假设。
    猜你喜欢
    • 2020-02-06
    • 1970-01-01
    • 2017-03-14
    • 2021-12-23
    • 2019-05-01
    • 2020-11-14
    • 2021-02-10
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多