代码之家  ›  专栏  ›  技术社区  ›  EmacsVI

Vue Test Utils/Jest-如何测试类方法是否在组件方法中调用

  •  1
  • EmacsVI  · 技术社区  · 6 年前

    我的单元测试有个有趣的问题。我的单元测试是为了点击组件内部的按钮而编写的。此按钮调用包含类实例的组件方法 Service (axios的包装类)。这个组件方法唯一做的就是调用 Service.requestPasswordReset() . 我的单元测试需要验证 Service.requestPasswordReset

    我知道我在正确地模拟我的服务类,因为这通过了我的单元测试:

    await Service.requestPasswordReset()
    expect(Service.requestPasswordReset).toHaveBeenCalled()
    

    我知道我在单击时正确地调用了方法,因为这通过了我的单元测试:

    await wrapper.find('button').trigger('click')
    expect(mockMethods.resend).toHaveBeenCalled()
    

    我只是不能让我的测试注册 方法被调用。有什么想法吗?

    <template lang="pug">
    Layout
        section
            header( class="text-center py-4 pb-12")
                h1( class="text-grey-boulder font-light mb-4") Recovery Email
                p( class="text-orange-yellow") A recovery email has been sent to your email address
    
            div( class="text-center")
                div( class="mb-6")
                    button(
                        type="button"
                        @click.stop="resend()"
                        class="bg-orange-coral font-bold text-white py-3 px-8 rounded-full w-48"
                    ) Resend Email
    </template>
    
    <script>
    import Layout from '@/layouts/MyLayout'
    import Service from '@/someDir/Service'
    export default {
        name: 'RecoveryEmailSent',
        page: {
            title: 'Recovery Email Sent',
        },
        components: {
            Layout,
        },
        data() {
            return {
                errorMessage: null
            }
        },
        computed: {
            userEmail() {
                const reg = this.$store.getters['registration']
                return reg ? reg.email : null
            },
        },
        methods: {
            async resend() {
                try {
                    await Service.requestPasswordReset({
                        email: this.userEmail,
                    })               
                } catch (error) {
                    this.errorMessage = error
                }
            },
        },
    }
    </script>
    

    服务.js

    import client from '@/clientDir/BaseClient'
    
    class Service {
        constructor() {
            this.client = client(baseUrl)
        }
    
        requestPasswordReset(request) {
            return this.client.post('/account_management/request_password_reset', request)
        }
    }
    
    export { Service }
    
    export default new Service()
    

    中的Service.js __mock__

    export default {
        requestPasswordReset: jest.fn(request => {
            return new Promise((resolve, reject) =>
                resolve({
                    data: {
                        statusCode: 'Success',
                    },
                })
            )
        })
    }
    

    jest.mock('@/someDir/Service')
    import { shallowMount, mount, createLocalVue } from '@vue/test-utils'
    import RecoveryEmailSent from './AccountManagement.RecoveryEmailSent'
    import Service from '@/someDir/Service'
    const localVue = createLocalVue()
    // localVue.use(Service) // <-- Tried this, didn't work
    
    describe('Recovery Email Sent', () => {
    
        it('should resend recovery email', async () => {
            const mockMethods = {
                resend: jest.fn()
            }
            const email = 'testemail@test.com'
            const wrapper = mount(RecoveryEmailSent, {
                localVue,
                computed: {
                    userEmail() {
                        return email
                    },
                },
                methods: mockMethods
            })
    
            // await Service.requestPasswordReset()
            await wrapper.find('button').trigger('click')
            expect(mockMethods.resend).toHaveBeenCalled()
            expect(Service.requestPasswordReset).toHaveBeenCalled()
        })
    })
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   EmacsVI    6 年前

    我想出来了。显然,开玩笑的 .toHaveBeenCalled() 如果有问题的方法是用参数调用的,则不返回true。你必须使用 .toHaveBeenCalledWith()

    这是我通过的测试代码

    it('should resend email hash', async () => {
        const email = 'testemail@test.com'
        const wrapper = mount(AccountManagementForgottenPasswordSubmitted, {
            localVue,
            computed: {
                userEmail() {
                    return email
                },
            },
        })
    
        await wrapper.find('button').trigger('click')
        expect(Service.requestPasswordReset).toHaveBeenCalledWith({
            email: email
        })
    })
    
        2
  •  0
  •   ittus    6 年前

    inject-loader 嘲笑你的服务

    基本思想:

    const RecoveryEmailSentInjector = require('!!vue-loader?inject!./AccountManagement.RecoveryEmailSent')
    import Service from '@/someDir/Service'
    
    const mockedServices = {
      '@/someDir/Service': Service
    }
    
    describe('Recovery Email Sent', () => {
    
        it('should resend recovery email', async () => {
          const RecoveryEmailSentWithMocks = RecoveryEmailSentInjector(mockedServices)
    
          const wrapper = mount(RecoveryEmailSentWithMocks, { 
            ...
          })
          await wrapper.find('button').trigger('click')
          expect(mockMethods.resend).toHaveBeenCalled()
          expect(mockedServices.requestPasswordReset).toHaveBeenCalled()
        })
    })