在创建的挂钩中模拟setIntervalvue.js

问题描述

我正在尝试在setInterval钩子中模拟created,但无论尝试如何 该函数从不调用。到目前为止,我所做的是在内部使用jest.usefaketimers 每次测试时,我都会使用jest.advanceTimersByTime(8000)检查是否调用了我的api。 我将不胜感激任何意见/帮助。谢谢

我的Vue文件

  created() {
    setInterval(() => this.checkStatus(),8000)
  },methods: {
    async checkStatus() {
      let activated = false
      if (!this.isLoading) {
        this.isLoading = true
        let res = await this.$UserApi.getUserActivateStatus(this.accountId)
        this.isLoading = false
        if (res.success) {
          activated = res.activated
        }
        if (activated) {
          console.log("activated")
        } else {
          console.log("error")
        }
      }
    }
  }

我的测试文件

import { shallowMount,config } from "@vue/test-utils"
import Step4 from "../../../login/smart_station/step4"

describe("Step4",() => {
  let wrapper
  const $route = {
    query: {
      account_id: "99"
    }
  }

  const mockGetUserActivateStatus = jest.fn(() =>
    Promise.resolve({ success: true,activated: true })
  )

  beforeEach(() => {
    wrapper = shallowMount(Step4,{
      mocks: {
        $UserApi: {
          getUserActivateStatus: mockGetUserActivateStatus
        }
      }
    })
    jest.usefaketimers()
  })

  it("activates status every 8secs",async () => {
    jest.advanceTimersByTime(9000)
    expect(mockGetUserActivateStatus).toHaveBeenCalled()
  })
})

解决方法

Jest的Timer Mocks用其自己的可控制版本替换了setInterval之类的本地计时器函数。

您的问题是,您要告诉Jest在创建并安装组件后替换这些功能。由于您在组件的setInterval挂钩中使用created,因此仍将使用实际版本。

jest.useFakeTimers()移至beforeEach设置功能的顶部

beforeEach(() => {
  jest.useFakeTimers()

  wrapper = shallowMount(Step4,{
    mocks: {
      $UserApi: {
        getUserActivateStatus: mockGetUserActivateStatus
      }
    }
  })
})