gpt4 book ai didi

javascript - 在 vuejs 中测试 firebase 函数

转载 作者:行者123 更新时间:2023-12-01 17:18:22 25 4
gpt4 key购买 nike

我想对我的 vue 组件进行单元测试。由于我正在使用 firebase,所以这有点困难。

首先,我创建了一个 __mocks__ 文件夹来包含我所有的模拟函数。在该文件夹中,我创建了 firebase.js:

import * as firebase from 'firebase';

const onAuthStateChanged = jest.fn();

const getRedirectResult = jest.fn(() => Promise.resolve({
user: {
displayName: 'redirectResultTestDisplayName',
email: 'redirectTest@test.com',
emailVerified: true,
},
}));

const sendEmailVerification = jest.fn(() => Promise.resolve('result of sendEmailVerification'));

const sendPasswordResetEmail = jest.fn(() => Promise.resolve());

const createUserWithEmailAndPassword = jest.fn(() => {
console.log('heeeeelllo');
Promise.resolve({
user: {
displayName: 'redirectResultTestDisplayName',
email: 'redirectTest@test.com',
emailVerified: true,
},
});
});

const signInWithEmailAndPassword = jest.fn(() => Promise.resolve('result of signInWithEmailAndPassword'));

const signInWithRedirect = jest.fn(() => Promise.resolve('result of signInWithRedirect'));

const initializeApp = jest // eslint-disable-line no-unused-vars
.spyOn(firebase, 'initializeApp')
.mockImplementation(() => ({
auth: () => ({
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
currentUser: {
sendEmailVerification,
},
signInWithRedirect,
}),
}));

jest.spyOn(firebase, 'auth').mockImplementation(() => ({
onAuthStateChanged,
currentUser: {
displayName: 'testDisplayName',
email: 'test@test.com',
emailVerified: true,
},
getRedirectResult,
sendPasswordResetEmail,
}));

firebase.auth.FacebookAuthProvider = jest.fn(() => {});
firebase.auth.GoogleAuthProvider = jest.fn(() => {});

这个文件,我取自:https://github.com/mrbenhowl/mocking-firebase-initializeApp-and-firebase-auth-using-jest

我要测试的组件称为 EmailSignupLogin。在这种特殊情况下,我想测试 registerViaEmail 方法:

methods: {
registerViaEmail() {
if (this.password.length > 0 && this.password === this.passwordReenter) {
firebase.auth().createUserWithEmailAndPassword(this.emailAdress, this.password).then((result) => {
const { user } = result;
console.log(result);
this.setUser(user);
this.$router.push('/stocks');
}).catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
this.error = errorMessage;
console.error(errorCode, errorMessage);
});
} else {
this.error = 'passwords not matching';
}
},
},

现在我的测试文件(email-signup-login.spec.js):

import { mount } from '@vue/test-utils';
import Vue from 'vue';
import EmailSignupLogin from '@/components/email-signup-login';

jest.mock('../../__mocks__/firebase');

describe('EmailSignupLogin', () => {
let wrapper;
const mockFunction = jest.fn();

beforeEach(() => {
wrapper = mount(EmailSignupLogin, {
data() {
return {
password: '123456',
passwordReenter: '123456',
emailAdress: 'test@test.com',
};
},
store: {
actions: {
setUser: mockFunction,
},
},
});
});

describe('methods', () => {
describe('#registerViaEmail', () => {
it('calls mockFunction', async () => {
await wrapper.vm.registerViaEmail();

expect(mockFunction).toHaveBeenCalled();
});
});
});
});

registerViaEmail 方法中,我调用了 setUser 操作,这是一个 vuex 操作。

问题是它似乎没有从 __mocks__/firebase.js 调用我模拟的函数。谁能告诉我为什么?

最佳答案

您的代码中出现了几个问题:

  1. registerViaEmail() 不是 async(不返回 Promise),因此 await 调用过早返回,此时您的测试会尝试断言尚未发生的事情。要解决这个问题,只需用 Promise 包裹函数体:
registerViaEmail() {
return new Promise((resolve, reject) => {
if (this.password.length > 0 && this.password === this.passwordReenter) {
firebase.auth().createUserWithEmailAndPassword(this.emailAdress, this.password).then((result) => {
//...
resolve()
}).catch((error) => {
//...
reject()
});
} else {
//...
reject()
}
})
},
  1. script你提到的不打算与 Jest __mocks__ 一起使用。脚本本身直接修改 firebase 对象,用模拟替换它的方法/属性。要使用该脚本,您只需要在导入使用firebase的测试模块之前导入它:
import './firebase-mock' // <-- order important
import EmailSignupLogin from '@/components/EmailSignupLogin'
  1. createUserWithEmailAndPassword 不返回任何内容。好像是originally returned the Promise ,但是你用console.log修改了它,忘记继续返回Promise,这阻止了这个方法被awaited(相同作为 #1 发行)。解决方案是返回 Promise:
const createUserWithEmailAndPassword = jest.fn(() => {
console.log('heeeeelllo')
return /*👈*/ Promise.resolve(/*...*/)
})
  1. createUserWithEmailAndPassword 是要在 EmailSignupLogin 中测试的方法,但它目前未在您的 auth 模拟对象中模拟。它仅在 initializeApp.auth 的返回中被模拟,但这不是它在 EmailSignupLogin 中使用的内容。要解决此问题,请将 createUserWithEmailAndPassword 复制到您的 auth 模拟对象:
jest.spyOn(firebase, 'auth').mockImplementation(() => ({
onAuthStateChanged,
currentUser: {
displayName: 'testDisplayName',
email: 'test@test.com',
emailVerified: true,
},
getRedirectResult,
sendPasswordResetEmail,
createUserWithEmailAndPassword, //👈
}));
  1. 在你的测试设置中,你用一个普通对象模拟了商店,但它实际上需要是 Vuex.Store 的一个实例:
mount({
//store: { /*...*/ }, //❌DON'T DO THIS
store: new Vuex.Store({ /*...*/ }) //✅
})

Github demo

关于javascript - 在 vuejs 中测试 firebase 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60418904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com