簡體   English   中英

嘗試在 Jest 中模擬 setInterval(),使用 jest.useFakeTimers(),未按預期工作,斷言導致類型匹配器錯誤

[英]Attempting to mock setInterval() in Jest, using jest.useFakeTimers(),not working as expected and assertions result in type matcher errors

我已經閱讀了此處的所有帖子和 Jest 文檔,但我似乎仍然做錯了什么。 我正在為使用全局 setInterval() function 的服務編寫單元測試。當我編寫測試時,我不斷收到以下錯誤:

expect(received).toHaveBeenCalledTimes(expected)

    Matcher error: received value must be a mock or spy function

    Received has type:  function
    Received has value: [Function anonymous]

      40 |
      41 |     expect(smartlook).toHaveBeenCalledTimes(2);
    > 42 |     expect(setInterval).toHaveBeenCalledTimes(1);
         |                         ^
      43 |   });
      44 | });

這是 function:

/**
 * trackSmartlook
 */
function trackSmartlook( eventType: string, eventName: string, properties = false ): void {
  if (window.smartlook) {
    window.smartlook.apply([eventType, eventName, properties]);
  } else {
    const checkSmartlookLoaded = setInterval(() => {
      if (window.smartlook) {
        window.smartlook.apply([eventType, eventName, properties]);
        clearInterval(checkSmartlookLoaded);
      }
    }, 1000);
  }
}

export default trackSmartlook;

這是測試文件:

import trackSmartlook from 'Services/app/SmartlookService';

const eventType      = 'track';
const eventName      = 'event name';

/**
 * Mocking window.smartlook
 */
Object.defineProperty(window, 'smartlook', {
  value   : jest.fn().mockImplementation(),
});

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

afterEach(() => {
  jest.runOnlyPendingTimers();
  jest.useRealTimers();
});

/**
 * Test SmartlookService
 */
describe('test SmartlookService', () => {
  it ('trackSmartlook calls setInterval and call window.smartlook twice', () => {
    const smartlook = jest.spyOn(window,'smartlook').mockImplementation();
    smartlook.mockReturnValue(undefined);

    trackSmartlook(eventName, eventType);

    jest.advanceTimersByTime(1001);

    expect(smartlook).toHaveBeenCalledTimes(2);
    expect(setInterval).toHaveBeenCalledTimes(1);
  });
});

我嘗試了 Jest 文檔中建議的所有內容。 即 jest.spyOn(global,'setInterval'), jest.useFakeTimers('legacy') 等,但我仍然得到相同的結果。 任何建議,將不勝感激。 開玩笑版本 27.0.1

嘗試使用jest.useFakeTimers('legacy')

我有這個例子,也許對你有幫助。 使用玩笑版本 27.5.1(“玩笑”:“^27.5.1”)。

import { shallowMount } from "@vue/test-utils";
import ProgressBar from '../ProgressBar.vue'

describe('ProgressBar.vue', () => {
  // Function to run before each test.
  beforeEach(() => {
    jest.useFakeTimers('legacy') // Replaces global timer functions. legacy to works setInterval return value mocks.
  })
  
  test('clears timer when finish is called', () => {
    jest.spyOn(window, 'clearInterval') // Spies on the clearInterval function.
    
    setInterval.mockReturnValue(123) // Configures setInterval to return 123.

    const wrapper = shallowMount(ProgressBar)
    wrapper.vm.start() // Calls start to start the timer.
    wrapper.vm.finish() // Calls clearInterval function.

    // Asserts that the clearInterval mock was called with the value returned from setInterval.
    expect(window.clearInterval).toHaveBeenCalledWith(123)
  })
})

進度條.vue:

<template>
  <div
    :class="{hidden: hidden}"
    :style="{width: percent + '%'}"
  >

  </div>
</template>

<script>
export default {
  data() {
    return {
      hidden: true,
      percent: 0
    }
  },
  methods: {
    start() {
      this.percent = 0
      this.hidden = false

      this.timer = setInterval(() => {
        this.percent++
      }, 100)
    },
    finish() {
      this.hidden = true
      this.percent = 100

      clearInterval(this.timer)
    }
  }
}
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM