Webpack中的require.context方法在Jest中找不到

最近在为新版的框架做Vue组件的单元测试,选择了Jest,但在测试某个组件时出现问题。

本来是要测试Login组件,但这个Login组件中引入了SvgIcon子组件,这个子组件中使用了Webpack的require.context方法来引入所有的svg资源,代码如下:

const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('@/assets/svg-icons', false, /\.svg$/)
requireAll(req)

当Jest测试这里的时候,出现错误提示:

图片描述

我该如何解决这个问题?? 或者说如何Mock这个方法?

阅读 9.8k
4 个回答

已解决,SegmentDefault上没有相关问题与答案,StockOverflow上的答案也是非常晦涩。在进一步研究require.context之后发现,这个函数就是用来引用资源的,但我引用的时机不会,写在了声明周期之外,下面是原来的代码:

<script type='text/ecmascript-6'>
// 引入所有的svg文件
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('../../assets/svg-icons', false, /\.svg$/)
requireAll(req)

export default {
  name: 'SvgIcon',

  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String
    }
  },
...

改动之后是这样的:

export default {
  ...

  created () {
    this.requireSvgs()
  },

  methods: {
    // 将引入资源的动作定义成了函数
    requireSvgs () {
      const requireAll = requireContext => requireContext.keys().map(requireContext)
      const req = require.context('../../assets/svg-icons', false, /\.svg$/)
      requireAll(req)
    }
  }
}

这样写,就可以通过测试了

import Vue from 'vue'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import ElementUI from 'element-ui'
import Vuex from 'vuex'
import SvgIcon from '@/components/base/SvgIcon'
import Login from '@/components/Login'

Vue.use(ElementUI)
Vue.component('svg-icon', SvgIcon)

// 独立构建Vue构造函数
const localVue = createLocalVue()
localVue.use(Vuex)

describe('对Login组件的单元测试', () => {
  let wrapper

  beforeEach(() => {
    wrapper = shallowMount(Login, {
      localVue
    })
  })

  afterEach(() => {
    wrapper.destroy()
  })

  test('验证Login组件是一个Vue组件', () => {
    expect(wrapper.isVueInstance()).toBeTruthy()
  })
})

记录在此,供有需要的朋友参考。

备注:第二天对代码进行了修改,把svg资源引用的代码从SvgIcon组件中删除,让SvgIcon组件简单化,它只用来渲染icon图标,这样也利于后面对此组件的测试,并将引入资源代码移植到了main.js中。

jest只走babel(babel-jest),不会走webpack,所以没辙。唯一的办法就是替换代码

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题