'How to spy beforeDestroy lifecycle in Nuxt test

I am trying to testing my lifecycle components using Nuxt and Typescript, and I want to make sure that the beforeDestroy lifecycle is called

index.vue

<template>
  <div>
    <h3>Bom will self destruct in {{ timeLeft }}</h3>
    <img class="bomb jump" src="https://pngimg.com/uploads/bomb/bomb_PNG5.png" alt="Bomb">
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

interface IData {
  interval: any
  counter: number
  timer: number
}

export default Vue.extend({
  data (): IData {
    return {
      interval: undefined,
      counter: 0,
      timer: 10
    }
  },
  computed: {
    timeLeft (): number {
      return this.timer - this.counter
    },
  },
  mounted () {
    this.interval = setInterval(() => {
      this.counter++
      if (this.counter === this.timer) {
        this.$destroy()
      }
    }, 1000)
  },
  beforeDestroy () {
    clearInterval(this.interval)
    console.log("Bye bye!")
  },
  destroyed () {
    this.$router.push('/')
  }
})
</script>

<style>
.bomb {
  width: 100px;
  height: 100px;
  margin: 0 auto;
}

.jump {
  transform-origin: 50% 50%;
  animation: jump .5s linear alternate infinite;
}

@keyframes jump {
  0%   {transform: translate3d(0,0,0) scale3d(1,1,1);}
  40%  {transform: translate3d(0,30%,0) scale3d(.7,1.5,1);}
  100% {transform: translate3d(0,100%,0) scale3d(1.5,.7,1);}
}

</style>

Lifecycle.spec.ts

import { shallowMount } from '@vue/test-utils'
import LifecycleFile from '@/pages/lifecycle/index.vue'

const $router = {
  push: jest.fn()
}

describe('Testing Lifecycle', () => {
  jest.useFakeTimers()
  const spyBeforeDestory = jest.spyOn(LifecycleFile as any, 'beforeDestroy')
  
  const wrapper = shallowMount(LifecycleFile, {
    mocks: {
      $router
    }
  })
  
  it('render', () => {
    expect(wrapper.exists()).toBe(true)
  })
  
  it('Interval must have defined value after mounting', () => {
    expect((wrapper.vm as any).interval).toBeDefined()
  })
  
  it('Test the counter', () => {
    expect((wrapper.vm as any).counter).toBe(0)
    jest.advanceTimersByTime(1000)
    expect((wrapper.vm as any).counter).toBe(1)
  })
  
  it('Check beforeDestroy', () => {
    jest.advanceTimersByTime(9000)
    expect((wrapper.vm as any).counter).toBe(10)
    expect(spyBeforeDestory).toHaveBeenCalled()
  })

  it('Must be destroyed', () => {
    expect(wrapper.exists()).toBe(false)
  })
})

But when i run it, I encounter error

  ● Test suite failed to run

    Cannot spy the beforeDestroy property because it is not a function; undefined given instead

       8 | describe('Testing Lifecycle', () => {
       9 |   jest.useFakeTimers()
    > 10 |   const spyBeforeDestory = jest.spyOn(LifecycleFile as any, 'beforeDestroy')
         |                                 ^
      11 |   
      12 |   const wrapper = shallowMount(LifecycleFile, {
      13 |     mocks: {

      at ModuleMocker.spyOn (node_modules/jest-mock/build/index.js:794:15)
      at test/Lifecycle.spec.ts:10:33
      at Object.<anonymous> (test/Lifecycle.spec.ts:8:1)

If I remove const spyBeforeDestory = jest.spyOn(LifecycleFile as any, 'beforeDestroy') and expect(spyBeforeDestory).toHaveBeenCalled() it run normally, I just want to know how to spy the beforeDestroy lifecycle

Thankyou!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source