【问题标题】:How to mock a plugin in Jest如何在 Jest 中模拟插件
【发布时间】:2019-12-26 22:38:38
【问题描述】:

我的单元测试设置不正确,这意味着我没有正确地模拟我导入的插件函数。

如何正确模拟我的 logData 函数?在插件中,函数返回未定义,这是由选择。我只需要确保我 console.log 传递给它的任何内容。

我得到的当前错误是“无法监视 logData 属性,因为它不是函数;改为未定义”

logData.js - 插件(只是 console.log 语句的包装器)

export function logData (dataToLog) {
  const isLoggingData = localStorage.getItem('isLoggingData')
  if (isLoggingData) {
    console.log(dataToLog)
  }
}

export default {
  install: function (Vue) {
    Vue.prototype.$logData = logData
  }
}

logData.spec.js - 我模拟了localStorage,但我需要模拟插件logData

import Vue from 'vue'
import { createLocalVue } from '@vue/test-utils'
import logData from './logData'

class LocalStorageMock {
  constructor () {
    this.store = {}
  }
  getItem (key) {
    return this.store[key] || null
  }
  setItem (key, value) {
    this.store[key] = value.toString()
  }
  removeItem (key) {
    delete this.store[key]
  }
}

global.localStorage = new LocalStorageMock()

const localVue = createLocalVue()
const dataToLog = 'data to be logged'
localVue.use(logData)

const mockLogDataFunction = jest.spyOn(localVue.prototype, 'logData')

describe('logData plugin', () => {
  // PASSES
  it('adds a $logData method to the Vue prototype', () => {
    console.log(wrapper.vm.$logData)
    expect(Vue.prototype.$logData).toBeUndefined()
    expect(typeof localVue.prototype.$logData).toBe('function')
  })
  // Now passes
  it('[positive] console.logs data passed to it', () => {
    global.localStorage.setItem('isLoggingData', true)
    const spy = jest.spyOn(global.console, 'log')
    localVue.prototype.$logData('data to be logged')
    expect(spy).toHaveBeenCalledWith(dataToLog)
    // expect(mockLogDataFunction).toHaveBeenCalled()
    // console.log(localVue)
    // expect(localVue.prototype.$logData(dataToLog)).toMatch('data to be logged')
  })
  // PASSES
  it('[negative] does not console.log data passed to it', () => {
    const spy = jest.spyOn(global.console, 'log')
    global.localStorage.removeItem('isLoggingData')
    localVue.prototype.$logData(dataToLog)
    expect(spy).not.toHaveBeenCalled()

    // const spy = jest.spyOn(this.$logData, 'console')
    // expect(localVue.prototype.$logData(dataToLog)).toBe(und efined)
    // expect(spy).toBe(undefined)
  })
})

【问题讨论】:

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


    【解决方案1】:

    你做错了。

    1. jest.spyOn(object, methodName)。您需要将localVue.prototype'logData' 作为参数传递,以跟踪是否调用了此方法。

    创建一个类似于jest.fn 的模拟函数,但也跟踪对 object[methodName]。返回一个 Jest 模拟函数。

    1. 检查方法是否被调用 – expect(spy).toHaveBeenCalled()

    所以改变你的一些代码行:

    const mockLogDataFunction = jest.spyOn(localVue.prototype, '$logData')
    
    // invoke it and then ensure that that method is really called
    localVue.prototype.$logData('foo')
    expect(mockLogDataFunction).toHaveBeenCalled()
    

    【讨论】:

    • 问题是,我实际上是在监视console.log 函数,正如你所知,它是全局的。所以我需要监视它,然后当我调用logData 时,我检查是否调用了console.log 以及传递给它的内容以进行阳性测试。而对于否定的,我断言 console.log 没有被调用。我更新了上面的代码。让我知道您的想法...感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 2021-06-09
    • 2021-11-02
    • 2021-08-20
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    相关资源
    最近更新 更多