繁体   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